﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;  // SerialPort
using Excel = Microsoft.Office.Interop.Excel; // Excel
using System.Threading; // 用于Excel
using System.IO;  // 用于保存txt文件
using System.Runtime.InteropServices;  // 用于保存配置信息
using System.Threading;  // 多线程操作
using System.Management; // 用于寻找到串口号的设备描述，注意：还需要在项目引用里面添加，否则也不行！
using findSerialPorts; 

using System.Diagnostics;  // 用于打开网址

namespace SuperPowerCAN_WeChat_TC4300_QQ_43058655
{
    public partial class Frm_Main : Form
    {
        public static Frm_Main f1;
        /*************************************用类体定义发送命令的函数！****************************************************/
        static BasicFunctionSetCommand_Class BFS = new BasicFunctionSetCommand_Class();
        byte[] BasicFunctionSet_Array = { BFS.SendHead0, BFS.SendHead1, BFS.FunctionCode, BFS.RunMode,BFS.tBS1,BFS.tBS2,BFS.BRP_H,BFS.BRP_L,BFS.ForbidAutomaticReSend,BFS.Dummy,
                                          BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,
                                          BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Dummy,BFS.Sum,BFS.SendTail,};
        /********************************************************************************************************************/
        static STM32ResetCommand_Class SRC = new STM32ResetCommand_Class();
        byte[] STM32ResetCommand_Array = { SRC.SendHead0, SRC.SendHead1, SRC.FunctionCode, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy,
                                           SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, 
                                           SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Dummy, SRC.Sum, SRC.SendTail,};
        /********************************************************************************************************************/
        static FilterSetCommand_Class FS = new FilterSetCommand_Class();
        byte[] FilterSetCommand_Array = { FS.SendHead0,FS.SendHead1,FS.FunctionCode,FS.FilterIndex,FS.OpenFilter,FS.FilterID_H,FS.FilterID_MH,FS.FilterID_ML,FS.FilterID_L,FS.FilterMask_H,
                                          FS.FilterMask_MH,FS.FilterMask_ML,FS.FilterMask_L,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,
                                          FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Dummy,FS.Sum,FS.SendTail,};
        /********************************************************************************************************************/
        static CANSendCommand_Class CS = new CANSendCommand_Class();
        byte[] CANSendCommand_Array = { CS.SendHead0,CS.SendHead1,CS.FunctionCode,CS.TIR_H,CS.TIR_MH,CS.TIR_ML,CS.TIR_L,CS.TDHR_H,CS.TDHR_MH,CS.TDHR_ML,
                                        CS.TDLR_L,CS.TDHR_H,CS.TDHR_MH,CS.TDHR_ML,CS.TDLR_L,CS.TDLR_H,CS.TDLR_MH,CS.TDLR_ML,CS.TDLR_L,CS.Dummy,
                                        CS.Dummy,CS.Dummy,CS.Dummy,CS.Dummy,CS.Dummy,CS.Dummy,CS.Dummy,CS.Dummy,CS.Sum,CS.SendTail,};
        /*******************************************************************************************************************/
        static ComRecv_Class CR = new ComRecv_Class();
        /**********************************************************/
        static StatusMsg_Class SM = new StatusMsg_Class();
        /***********************************************************/
        static Send_Class MS = new Send_Class();
        byte[] CANMainSendData_Array = new byte[30];
        /***********************************************************/
        public DataGridViewDisplay_Class DGVD = new DataGridViewDisplay_Class();

       
        public UInt16 DGVDisBufSize = 65535;
        private DataGridViewDisplay_Class[] DGVDis = new DataGridViewDisplay_Class[65535];  // 定义数组
        public UInt16 pDGVDisRead = 0;
        public UInt16 pDGVDisWrite = 0;

        public DataGridViewDispalyForThread_Class DGVDisplay = new DataGridViewDispalyForThread_Class();

        /***********************************************************/
        CANRecvData_Class CRD = new CANRecvData_Class();
        /***********************************************************/
        ClearCount_Class CC = new ClearCount_Class();
        byte[] ClearCount_Array = new byte[30];
        /***********************************************************/
        byte forIntervalTrasnfer = 0;
        byte scanSum = 0;
        /***********************************************************/
        /*************************  ↓ 下面都是为了配置信息而设置的 ↓ **********************************/
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);//系统dll导入ini写函数
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);//系统dll导入ini读函数
        string IniFile = System.AppDomain.CurrentDomain.BaseDirectory + "CAN调试器配置信息_WeChat_TC4300_QQ_43058655.ini";//ini文件名

        public StringBuilder sb = new StringBuilder("");  // 用于Txt的文本显示

        StringBuilder tab1_cmb_ModeSel = new StringBuilder(255);
        StringBuilder tab1_cmb_baudrate = new StringBuilder(255);
        StringBuilder tab1_chb_CustomEnable = new StringBuilder(255);
        StringBuilder tab1_chb_autoRetransfer = new StringBuilder(255);
        StringBuilder tab1_txb_tbs1 = new StringBuilder(255);
        StringBuilder tab1_txb_tbs2 = new StringBuilder(255);
        StringBuilder tab1_txb_brp = new StringBuilder(255);
        StringBuilder tab1_txb_calbaudrate = new StringBuilder(255);

        StringBuilder tab2_txb_ID0 = new StringBuilder(255);
        StringBuilder tab2_txb_ID1 = new StringBuilder(255);
        StringBuilder tab2_txb_ID2 = new StringBuilder(255);
        StringBuilder tab2_txb_ID3 = new StringBuilder(255);
        StringBuilder tab2_txb_ID4 = new StringBuilder(255);
        StringBuilder tab2_txb_ID5 = new StringBuilder(255);
        StringBuilder tab2_txb_ID6 = new StringBuilder(255);
        StringBuilder tab2_txb_ID7 = new StringBuilder(255);
        StringBuilder tab2_txb_ID8 = new StringBuilder(255);
        StringBuilder tab2_txb_ID9 = new StringBuilder(255);
        StringBuilder tab2_txb_ID10 = new StringBuilder(255);
        StringBuilder tab2_txb_ID11 = new StringBuilder(255);
        StringBuilder tab2_txb_ID12 = new StringBuilder(255);
        StringBuilder tab2_txb_ID13 = new StringBuilder(255);
        StringBuilder tab2_txb_ID14 = new StringBuilder(255);

        StringBuilder tab2_txb_MASK0 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK1 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK2 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK3 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK4 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK5 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK6 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK7 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK8 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK9 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK10 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK11 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK12 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK13 = new StringBuilder(255);
        StringBuilder tab2_txb_MASK14 = new StringBuilder(255);


        StringBuilder tab3_chb_IDType0 = new StringBuilder(255);
        StringBuilder tab3_chb_IDType1= new StringBuilder(255);
        StringBuilder tab3_chb_IDType2 = new StringBuilder(255);
        StringBuilder tab3_chb_IDType3 = new StringBuilder(255);
        StringBuilder tab3_chb_IDType4 = new StringBuilder(255);
        StringBuilder tab3_chb_IDType5 = new StringBuilder(255);

        StringBuilder tab3_chb_DataType0 = new StringBuilder(255);
        StringBuilder tab3_chb_DataType1 = new StringBuilder(255);
        StringBuilder tab3_chb_DataType2 = new StringBuilder(255);
        StringBuilder tab3_chb_DataType3 = new StringBuilder(255);
        StringBuilder tab3_chb_DataType4 = new StringBuilder(255);
        StringBuilder tab3_chb_DataType5 = new StringBuilder(255);

        StringBuilder tab3_txb_ID0 = new StringBuilder(255);
        StringBuilder tab3_txb_ID1 = new StringBuilder(255);
        StringBuilder tab3_txb_ID2 = new StringBuilder(255);
        StringBuilder tab3_txb_ID3 = new StringBuilder(255);
        StringBuilder tab3_txb_ID4 = new StringBuilder(255);
        StringBuilder tab3_txb_ID5 = new StringBuilder(255);

        StringBuilder tab3_txb_Data0 = new StringBuilder(255);
        StringBuilder tab3_txb_Data1 = new StringBuilder(255);
        StringBuilder tab3_txb_Data2 = new StringBuilder(255);
        StringBuilder tab3_txb_Data3 = new StringBuilder(255);
        StringBuilder tab3_txb_Data4 = new StringBuilder(255);
        StringBuilder tab3_txb_Data5 = new StringBuilder(255);

        StringBuilder tab3_txb_Time0 = new StringBuilder(255);
        StringBuilder tab3_txb_Time1 = new StringBuilder(255);
        StringBuilder tab3_txb_Time2 = new StringBuilder(255);
        StringBuilder tab3_txb_Time3 = new StringBuilder(255);
        StringBuilder tab3_txb_Time4 = new StringBuilder(255);
        StringBuilder tab3_txb_Time5 = new StringBuilder(255);

        StringBuilder pl_chb1 = new StringBuilder(255);
        StringBuilder pl_chb2 = new StringBuilder(255);
        StringBuilder pl_chb3 = new StringBuilder(255);
        StringBuilder pl_chb4 = new StringBuilder(255);
        StringBuilder pl_chb5 = new StringBuilder(255);
        StringBuilder pl_chb6 = new StringBuilder(255);
        StringBuilder pl_chb7 = new StringBuilder(255);
        StringBuilder pl_chb8 = new StringBuilder(255);
        StringBuilder pl_chb9 = new StringBuilder(255);
        StringBuilder pl_chb10 = new StringBuilder(255);
        StringBuilder pl_chb11 = new StringBuilder(255);
        StringBuilder pl_chb12 = new StringBuilder(255);
        StringBuilder pl_chb13 = new StringBuilder(255);
        StringBuilder pl_chb14 = new StringBuilder(255);
        StringBuilder pl_chb15 = new StringBuilder(255);
        StringBuilder pl_chb16 = new StringBuilder(255);
        StringBuilder pl_chb17 = new StringBuilder(255);
        StringBuilder pl_chb18 = new StringBuilder(255);
        StringBuilder pl_chb19 = new StringBuilder(255);
        StringBuilder pl_chb20 = new StringBuilder(255);

        StringBuilder pl_txbSave1 = new StringBuilder(255);
        StringBuilder pl_txbSave2 = new StringBuilder(255);
        StringBuilder pl_txbSave3 = new StringBuilder(255);
        StringBuilder pl_txbSave4 = new StringBuilder(255);
        StringBuilder pl_txbSave5 = new StringBuilder(255);
        StringBuilder pl_txbSave6 = new StringBuilder(255);
        StringBuilder pl_txbSave7 = new StringBuilder(255);
        StringBuilder pl_txbSave8 = new StringBuilder(255);
        StringBuilder pl_txbSave9 = new StringBuilder(255);
        StringBuilder pl_txbSave10 = new StringBuilder(255);
        StringBuilder pl_txbSave11 = new StringBuilder(255);
        StringBuilder pl_txbSave12 = new StringBuilder(255);
        StringBuilder pl_txbSave13 = new StringBuilder(255);
        StringBuilder pl_txbSave14 = new StringBuilder(255);
        StringBuilder pl_txbSave15 = new StringBuilder(255);
        StringBuilder pl_txbSave16 = new StringBuilder(255);
        StringBuilder pl_txbSave17 = new StringBuilder(255);
        StringBuilder pl_txbSave18 = new StringBuilder(255);
        StringBuilder pl_txbSave19 = new StringBuilder(255);
        StringBuilder pl_txbSave20 = new StringBuilder(255);

        StringBuilder pl_cmb_IDType1 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType2 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType3 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType4 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType5 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType6 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType7 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType8 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType9 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType10 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType11 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType12 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType13 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType14 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType15 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType16 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType17 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType18 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType19 = new StringBuilder(255);
        StringBuilder pl_cmb_IDType20 = new StringBuilder(255);

        StringBuilder pl_cmb_DataType1 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType2 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType3 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType4 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType5 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType6 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType7 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType8 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType9 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType10 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType11 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType12 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType13 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType14 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType15 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType16 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType17 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType18 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType19 = new StringBuilder(255);
        StringBuilder pl_cmb_DataType20 = new StringBuilder(255);

        StringBuilder pl_txb_ID1 = new StringBuilder(255);
        StringBuilder pl_txb_ID2 = new StringBuilder(255);
        StringBuilder pl_txb_ID3 = new StringBuilder(255);
        StringBuilder pl_txb_ID4 = new StringBuilder(255);
        StringBuilder pl_txb_ID5 = new StringBuilder(255);
        StringBuilder pl_txb_ID6 = new StringBuilder(255);
        StringBuilder pl_txb_ID7 = new StringBuilder(255);
        StringBuilder pl_txb_ID8 = new StringBuilder(255);
        StringBuilder pl_txb_ID9 = new StringBuilder(255);
        StringBuilder pl_txb_ID10 = new StringBuilder(255);
        StringBuilder pl_txb_ID11 = new StringBuilder(255);
        StringBuilder pl_txb_ID12 = new StringBuilder(255);
        StringBuilder pl_txb_ID13 = new StringBuilder(255);
        StringBuilder pl_txb_ID14 = new StringBuilder(255);
        StringBuilder pl_txb_ID15 = new StringBuilder(255);
        StringBuilder pl_txb_ID16 = new StringBuilder(255);
        StringBuilder pl_txb_ID17 = new StringBuilder(255);
        StringBuilder pl_txb_ID18 = new StringBuilder(255);
        StringBuilder pl_txb_ID19 = new StringBuilder(255);
        StringBuilder pl_txb_ID20 = new StringBuilder(255);

        StringBuilder pl_txb_Data1 = new StringBuilder(255);
        StringBuilder pl_txb_Data2 = new StringBuilder(255);
        StringBuilder pl_txb_Data3 = new StringBuilder(255);
        StringBuilder pl_txb_Data4 = new StringBuilder(255);
        StringBuilder pl_txb_Data5 = new StringBuilder(255);
        StringBuilder pl_txb_Data6 = new StringBuilder(255);
        StringBuilder pl_txb_Data7 = new StringBuilder(255);
        StringBuilder pl_txb_Data8 = new StringBuilder(255);
        StringBuilder pl_txb_Data9 = new StringBuilder(255);
        StringBuilder pl_txb_Data10 = new StringBuilder(255);
        StringBuilder pl_txb_Data11 = new StringBuilder(255);
        StringBuilder pl_txb_Data12 = new StringBuilder(255);
        StringBuilder pl_txb_Data13 = new StringBuilder(255);
        StringBuilder pl_txb_Data14 = new StringBuilder(255);
        StringBuilder pl_txb_Data15 = new StringBuilder(255);
        StringBuilder pl_txb_Data16 = new StringBuilder(255);
        StringBuilder pl_txb_Data17 = new StringBuilder(255);
        StringBuilder pl_txb_Data18 = new StringBuilder(255);
        StringBuilder pl_txb_Data19 = new StringBuilder(255);
        StringBuilder pl_txb_Data20 = new StringBuilder(255);

        StringBuilder pl_txb_Time = new StringBuilder(255);

        /*************************  ↑ 下面都是为了配置信息而设置的 ↑ **********************************/
        bool toDelIniWhenClosing = false;
        public Frm_Main()
        {
            InitializeComponent();
            f1 = this;
            
        }

        private Object thisLock = new object();
        public void DataViewDisplayFun()  // 多线程函数，用于处理DataView控件的显示问题！
        {
          //  dataGridView1.Rows.Add("0","2","3","4","5");
            while(true)
            {
                //if ((((DGVDisplay.pWrite + DGVDisplay.BufSize) - DGVDisplay.pRead) % DGVDisplay.BufSize) > 0)  //说明有数据
                //{
                //    do
                //    {
                //        dataGridView1.Rows.Add(
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].Index.ToString(),
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].TransferDir,
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].OperateTime,
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].IDType,
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].DataType,
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].FrameID.ToString("X").PadLeft(8, '0'),
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].DataLength.ToString(),
                //            DGVDisplay.DataGridViewDisplay[DGVDisplay.pRead].Data
                //            );
                //        DGVDisplay.pRead++;
                //        DGVDisplay.pRead %= DGVDisplay.BufSize;
                //        if (dataGridView1.RowCount >= 2)
                //        {
                //            dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;
                //        }
                //    } while ((((DGVDisplay.pWrite + DGVDisplay.BufSize) - DGVDisplay.pRead) % DGVDisplay.BufSize) > 0);
                //}
                //else
                //{
                //    return;
                //}

            //goon:
            //    try
            //    {
                //lock (thisLock)   // 锁定线程。但是不知道原因。
                //{
                //    try  // 容易出错，但是不知道原因，而且可想而知，其查找难度比较大。
                //    {
                //        if ((((pDGVDisWrite + DGVDisBufSize) - pDGVDisRead) % DGVDisBufSize) > 0)  //说明有数据
                //        {
                //            do
                //            {
                //                dataGridView1.Rows.Add(
                //                    DGVDis[pDGVDisRead].Index.ToString(),
                //                    DGVDis[pDGVDisRead].TransferDir,
                //                    DGVDis[pDGVDisRead].OperateTime,
                //                    DGVDis[pDGVDisRead].IDType,
                //                    DGVDis[pDGVDisRead].DataType,
                //                    DGVDis[pDGVDisRead].FrameID.ToString("X").PadLeft(8, '0'),
                //                    DGVDis[pDGVDisRead].DataLength.ToString(),
                //                    DGVDis[pDGVDisRead].Data
                //                    );
                //                pDGVDisRead++;
                //                pDGVDisRead %= DGVDisBufSize;
                //                try
                //                {
                //                    if (dataGridView1.RowCount >= 2)
                //                    {
                //                        dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;
                //                    }
                //                }
                //                catch { }
                //            } while ((((pDGVDisWrite + DGVDisBufSize) - pDGVDisRead) % DGVDisBufSize) > 0);
                //        }
                //        else
                //        {
                //            return;
                //        }
                //    }
                //    catch
                //    { }
                //}
                //}
                //catch
                //{
                //   // goto goon;
                //}
            }
        }
    //{
    //    //private static object obj = new object();
    //    //private delegate void ChangeFunction( PackageMessage pm,string Message);

    //}

        private void btnPin_Click(object sender, EventArgs e)
        {
            switch(this.TopMost)
            {
                case true:
                    this.TopMost = false;
                    this.btnPin.BackgroundImage = global::SuperPowerCAN_WeChat_TC4300_QQ_43058655.Properties.Resources.Pin0;
                    this.toolTip1.SetToolTip(this.btnPin, "前端显示");
                    break;
                case false:
                    this.TopMost = true;
                    this.btnPin.BackgroundImage = global::SuperPowerCAN_WeChat_TC4300_QQ_43058655.Properties.Resources.UnPin0;
                    this.toolTip1.SetToolTip(this.btnPin, "取消前端显示");
                    break;
                default: break;
            }
        }
        public void InitCombox()
        {
            foreach (Control ctl in this.gb_CanFunction.Controls)
            {
                if (ctl is ComboBox)
                {
                    ComboBox cmb_All = (ComboBox)ctl;
                    cmb_All.SelectedIndex = 0;
                }
            }
            foreach (Control ctl in this.pl_SendBatch.Controls)
            {
                if (ctl is ComboBox)
                {
                    ComboBox cmb_All = (ComboBox)ctl;
                    cmb_All.SelectedIndex = 0;
                }
            }
            foreach (Control ctl in this.pl_MainSend.Controls)
            {
                if (ctl is ComboBox)
                {
                    ComboBox cmb_All = (ComboBox)ctl;
                    cmb_All.SelectedIndex = 0;
                }
            }
        }

        private void Frm_Main_Load(object sender, EventArgs e)
        {
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;  // 防止线程间的操作，虽然不知道这是什么

            chb_AtuoRetransfer.Visible = false;
            label8.Visible = false;

            this.Width = 800;
            this.Height = 600;
            SerialPortFresh();
            InitCombox();
            LoadCFG();

            //Thread Display_Thread = new System.Threading.Thread(new ThreadStart(DataViewDisplayFun));
            //Display_Thread.Start();
            //Display_Thread.IsBackground = true;  // 后台进程，主程序结束，这个线程也要结束！
          //  Thread.Sleep(0);
          //  Thread.Sleep(2000);  // 阻塞调用！
            
         //   Display_Thread.Abort();
            for (UInt16 i = 0; i < DGVDisBufSize;i++ )  // 记住一定要初始化一次，用new关键字！
            {
                DGVDis[i] = new DataGridViewDisplay_Class();
            }
            {//下面是为了防止卡CPU而在函数初始化的时候关闭批量发送窗口的批量发送功能
                chb_All.Visible = false;
                btn_SendCycle.Visible = false;
                btn_CycleSendCancle.Visible = false;
                lab_cycleTimeInterval.Visible = false;
                txb_SendCycleTime.Visible = false;
            }
        }

        private void 打开批量发送窗口1ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Frm_SendArray Frm2 = new Frm_SendArray();
           // Frm2.Owner = this;
            Frm2.Show();
        }
        private void btn_LeftExtend_Click(object sender, EventArgs e)
        {
            if (Screen.PrimaryScreen.WorkingArea.Width >= 1490)
            {
                this.Width = 1490;  // 若超出边界，则不能达到这个设定的宽度
            }
            else
            {
                MessageBox.Show("屏幕分辨率不能容纳！请调整分辨率，或者点击：打开批量发送窗口","提示");
            }
        }

        private void btn_LeftShrink_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
                this.Height = Screen.PrimaryScreen.WorkingArea.Height;
                this.Top = 0;
                this.Left = 0;
                this.Width = 800;
            }
            else
            {
                this.Width = 800;
            }
        }

        private void btn_UpDownShrink_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
                this.Width = Screen.PrimaryScreen.WorkingArea.Height;
                this.Left = 0;
                this.Height = 600;
            }
            else
            {
                this.Height = 600;
            }
        }

        private void btn_UpDownExtend_Click(object sender, EventArgs e)
        {
            this.Height = Screen.PrimaryScreen.WorkingArea.Height;
            this.Top = 0;
        }

        private void btn_Adapter_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
                this.Height = Screen.PrimaryScreen.WorkingArea.Height;
                this.Top = 0;
                this.Width = 800;
            }
            else
            {
                this.Height = Screen.PrimaryScreen.WorkingArea.Height;
                this.Top = 0;
                this.Width = 800;
            }
        }


        private void tsm_StatusStripDisplay1_Click(object sender, EventArgs e)
        {
            switch (tsm_StatusStripDisplay1.Checked)
            {
                case true:
                    tsm_StatusStripDisplay1.Checked = false;
                    statusStrip1.Visible = false;
                    break;
                case false:
                    tsm_StatusStripDisplay1.Checked = true;
                    statusStrip1.Visible = true;
                    break;
                default: break;
            }
        }

        private void tsm_StatusStripDisplay2_Click(object sender, EventArgs e)
        {
            switch (tsm_StatusStripDisplay2.Checked)
            {
                case true:
                    tsm_StatusStripDisplay2.Checked = false;
                    statusStrip2.Visible = false;
                    break;
                case false:
                    tsm_StatusStripDisplay2.Checked = true;
                    statusStrip2.Visible = true;
                    break;
                default: break;
            }
        }

        private void tsm_OpenSendArrayWindow_Click(object sender, EventArgs e)
        {
            Frm_SendArray Frm2 = new Frm_SendArray();
            // Frm2.Owner = this;
            Frm2.Show();
            tsm_OpenSendArrayWindow.Enabled = false;
        }
   /**************************************************************/
        public void SerialPortFresh( )  // 刷新串口函数
        {
            cmb_SerialPortIndex.Items.Clear();
            cmb_SerialPortIndex.Text = string.Empty;
            string[] ports = Win32api_findSerialPorts.MulGetHardwareInfo(Win32api_findSerialPorts.HardwareEnum.Win32_PnPEntity, "Name"); // 使用WPI接口
            if (ports != null)
            {
                string[] rebuildPorts = new string[ports.Length];
                for (byte i = 0; i < ports.Length; i++)  // 下面的我也感觉到也可以优化
                {
                    for (byte j = 0; j < ports[i].Length; j++)
                    {
                        if ((ports[i][j] == '(')
                            && ports[i][j + 1] == 'C'
                            && (ports[i][j + 2] == 'O')
                            && ports[i][j + 3] == 'M'
                            )
                        {
                            if (ports[i][j + 5] == ')') // (COMn) 形式 
                            {
                                rebuildPorts[i] = "COM" + ports[i][j + 4] + " " + ports[i].Substring(0, j - 1);
                            }
                            else if (ports[i][j + 6] == ')') // (COMnn) 形式 
                            {
                                rebuildPorts[i] = "COM" + ports[i][j + 4] + ports[i][j + 5] + " " + ports[i].Substring(0, j - 1);
                            }
                            else if (ports[i][j + 7] == ')') // (COMnnn) 形式 
                            {
                                rebuildPorts[i] = "COM" + ports[i][j + 4] + +ports[i][j + 5] + ports[i][j + 6] + " " + ports[i].Substring(0, j - 1);
                            }
                            else if (ports[i][j + 8] == ')') // (COMnnnn) 形式 
                            {
                                rebuildPorts[i] = "COM" + ports[i][j + 4] + ports[i][j + 5] + ports[i][j + 5] + ports[i][j + 7] + " " + ports[i].Substring(0, j - 1);
                            }
                            else
                            {
                                rebuildPorts[i] = "illegal Comport";
                            }
                        }
                    }
                }
                cmb_SerialPortIndex.Items.AddRange(rebuildPorts);
                cmb_SerialPortIndex.SelectedIndex = cmb_SerialPortIndex.Items.Count > 0 ? 0 : -1;
            }
            else  // 几乎不会出现这种错误
            {
                MessageBox.Show("寻找COM口出错！");
                cmb_SerialPortIndex.Text = null;
            }
        }
         /****************下面的函数：为了实现串口可以根据USB事件来检测更新串口*******************/
        public const int WM_DEVICECHANGE = 0x0219;//WM_DeviceChange
        public enum WM_DEVICECHANGE_WPPARAMS
        {
            DBT_DEVICEARRIVAL = 0x8000,//DeviceArray
            DBT_DEVICEREMOVECOMPLETE = 0x8004,//DeviceMoveComplete
        };

        protected override void WndProc(ref Message m)
        {
            try
            {
                if (m.Msg == WM_DEVICECHANGE)
                {
                    switch ((WM_DEVICECHANGE_WPPARAMS)(m.WParam.ToInt32()))
                    {
                        case WM_DEVICECHANGE_WPPARAMS.DBT_DEVICEARRIVAL:
                            tmr_StrartRefreshCom.Enabled = Enabled;  // 根据发现，如果直接使用上面的操作的方式，会出现报错。所以用单次定时器处理。
                            break;
                        case WM_DEVICECHANGE_WPPARAMS.DBT_DEVICEREMOVECOMPLETE: //卸载
                            tmr_StrartRefreshCom.Enabled = Enabled;  // 根据发现，如果直接使用上面的操作的方式，会出现报错。所以用单次定时器处理。
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            base.WndProc(ref m);
        }

        private void ts_btn_RefreshSerialPoat_Click(object sender, EventArgs e)
        {
            SerialPortFresh();
        }

        public byte GetSumForCommand( byte[] Array )  // 专用求和函数
        {
           byte Sum = 0;
           for(byte temp=0;temp<=27;temp++)
           {
               Sum = (byte)(Sum + Array[temp]);
           }
           return Sum;
        }
        private void tsm_ResetSTM32_Click(object sender, EventArgs e)
        {
            if( serialPort1.IsOpen == true )
            {
                serialPort1.Write(STM32ResetCommand_Array, 0, 30); // 发送30个数据
            }
            else
            {
                MessageBox.Show("错误003:请打开对应串口","提示");
            }
        }


       
        void ComProcess( )
        {
            byte[] dataBuf = new byte[CR.MinLen]; 
            if( (((CR.pWrite+CR.MaxLength)-CR.pRead) % CR.MaxLength) >= CR.MinLen )
            do
            {
                for( byte i=0;i<CR.MinLen;i++ )
                {
                    dataBuf[i] = CR.ComRecvBuf[(CR.pRead + i) % CR.MaxLength];
                }
                if( (dataBuf[0]==0xAA) && (dataBuf[1]==0x55) && (dataBuf[CR.MinLen-1]==0x88) )
                {
                    //if( GetSumForCommand(dataBuf) == dataBuf[28])  // 为了提升性能，这个和检验功能去掉
                    {
                        switch(dataBuf[2])
                        {
                            case 1:  // 
                                SM.FilterEnabledSum = dataBuf[3];
                                SM.ErrorWarningFlag = dataBuf[4];
                                SM.ErrorPassiveFlag = dataBuf[5];
                                SM.OffLineFlag = dataBuf[6];
                                SM.LastErrorCode = dataBuf[7];
                                SM.TransferErrorSum = dataBuf[8];
                                SM.RecvErrorSum = dataBuf[9];
                                SM.Baudrate =(UInt32)( (dataBuf[10]<<16)+(dataBuf[11]<<8)+(dataBuf[12]) );
                                SM.TransferOrderSum = (UInt32)( (dataBuf[13]<<24)+(dataBuf[14]<<16)+(dataBuf[15]<<8)+dataBuf[16] );
                                SM.TransferSucessedSum = (UInt32)( (dataBuf[17]<<24)+(dataBuf[18]<<16)+(dataBuf[19]<<8)+dataBuf[20] );
                                SM.TransferFailedSum = (UInt32)( (dataBuf[21]<<24)+(dataBuf[22]<<16)+(dataBuf[23]<<8)+dataBuf[24] );
                                SM.WorkMode = dataBuf[25];
                                SM.AutoRetransferEnable = dataBuf[26];

                                ts_FilterEnabledSum.Text = SM.FilterEnabledSum.ToString();
                                if (SM.OffLineFlag == 0)
                                    ts_OffLineFlag.Text = "在线";
                                else
                                    ts_OffLineFlag.Text = "离线";
                                switch (SM.LastErrorCode)
                                {
                                    case 0:
                                        ts_LastErrorCode.Text = "没有错误";
                                        break;
                                    case 1:
                                        ts_LastErrorCode.Text = "位填充错";
                                        break;
                                    case 2:
                                        ts_LastErrorCode.Text = "格式(From)错";
                                        break;
                                    case 3:
                                        ts_LastErrorCode.Text = "确认(ACK)错";
                                        break;
                                    case 4:
                                        ts_LastErrorCode.Text = "隐性位错";
                                        break;
                                    case 5:
                                        ts_LastErrorCode.Text = "显性位错";
                                        break;
                                    case 6:
                                        ts_LastErrorCode.Text = "CRC错";
                                        break;
                                    case 7:
                                        ts_LastErrorCode.Text = "由软件设置";
                                        break;
                                    default:
                                        break;
                                }
                                
                                ts_TransferErrorSum.Text = SM.TransferErrorSum.ToString();
                                ts_RecvErrorSum.Text = SM.RecvErrorSum.ToString();
                                ts_Baudrate.Text = SM.Baudrate.ToString() + "bps";
                               
                                ts_TransferOrderSum.Text = SM.TransferOrderSum.ToString();
                                ts_TransferSucessedSum.Text = SM.TransferSucessedSum.ToString();
                                ts_TransferFailedSum.Text = SM.TransferFailedSum.ToString();
                                {
                                    switch (SM.WorkMode)
                                    {
                                        case 0:
                                            ts_WorkMode.Text = "正常模式";
                                            break;
                                        case 1:
                                            ts_WorkMode.Text = "环回模式";
                                            break;
                                        case 2:
                                            ts_WorkMode.Text = "静默模式";
                                            break;
                                        case 3:
                                            ts_WorkMode.Text = "环回静默";
                                            break;
                                        default:
                                            MessageBox.Show("错误xxx：未知的工作模式", "提示");
                                            break;
                                    }
                                }
                                if (SM.AutoRetransferEnable == 0)
                                    ts_AutoRetransferEnable.Text = "否";
                                else
                                    ts_AutoRetransferEnable.Text = "是";
                                break;
                            case 2:
                                SM.RecvSucessedSum = (UInt32)((dataBuf[3] << 24) + (dataBuf[4] << 16) + (dataBuf[5] << 8) + dataBuf[6]);
                                ts_RecvSucessedSum.Text = SM.RecvSucessedSum.ToString();
                                break;
                            case 3:
                                UInt32 RIR_Tmp = (UInt32)((dataBuf[3]<<24) + (dataBuf[4]<<16) + (dataBuf[5]<<8)+ dataBuf[6] );
                                UInt32 RDTR_Tmp = (UInt32)((dataBuf[7]<<24) + (dataBuf[8]<<16) + (dataBuf[9]<<8)+ dataBuf[10] );
                                UInt32 RDHR_Tmp = (UInt32)((dataBuf[11]<<24) + (dataBuf[12]<<16) + (dataBuf[13]<<8)+ dataBuf[14] );
                                UInt32 RDLR_Tmp = (UInt32)((dataBuf[15]<<24) + (dataBuf[16]<<16) + (dataBuf[17]<<8)+ dataBuf[18] );
                                CRD.IDType = (byte)((RIR_Tmp>>2)&0x01);
                                switch(CRD.IDType)
                                {
                                    case 0: // 标准帧
                                        CRD.StandardID = (UInt16)(RIR_Tmp >> 21);
                                        DGVD.IDType = "标准帧";
                                        DGVD.FrameID = (UInt32)CRD.StandardID;
                                        break;
                                    case 1: // 扩展帧
                                        CRD.ExternID = (UInt32)(RIR_Tmp >> 3);
                                        DGVD.IDType = "扩展帧";
                                        DGVD.FrameID = (UInt32)CRD.ExternID;
                                        break;
                                    default: break;
                                }
                                CRD.DataType = (byte)((RIR_Tmp>>1)&0x01);
                                switch(CRD.DataType)
                                {
                                    case 0: // 数据帧
                                        DGVD.DataType = "数据帧";
                                        DGVD.DataLength = (byte)(RDTR_Tmp & 0x0F);
                                        CRD.Data[0] = (byte)(RDLR_Tmp);
                                        CRD.Data[1] = (byte)(RDLR_Tmp>>8);
                                        CRD.Data[2] = (byte)(RDLR_Tmp>>16);
                                        CRD.Data[3] = (byte)(RDLR_Tmp>>24);
                                        CRD.Data[4] = (byte)(RDHR_Tmp);
                                        CRD.Data[5] = (byte)(RDHR_Tmp>>8);
                                        CRD.Data[6] = (byte)(RDHR_Tmp>>16);
                                        CRD.Data[7] = (byte)(RDHR_Tmp>>24);
                                        DGVD.Data = string.Empty;
                                        if (DGVD.DataLength > 0)
                                        {
                                            for (byte temp0 = 0; temp0 < DGVD.DataLength; temp0++)
                                            {
                                                DGVD.Data += (CRD.Data[temp0].ToString("X").PadLeft(2, '0') + ' ');
                                            }
                                        }
                                        else
                                            DGVD.Data = "--";
                                            break;
                                    case 1: // 远程帧
                                        DGVD.DataType = "远程帧";
                                        DGVD.DataLength = 0;
                                        DGVD.Data = "--";
                                        break;
                                    default: break;
                                }
                                DGVD.Index++;
                                DGVD.TransferDir = "接收";
                                DGVD.OperateTime = DateTime.Now.ToString("yy-MM-dd HH:mm:ss:f");

                                //this.dataGridView1.ScrollBars = System.Windows.Forms.ScrollBars.None;
                                // 下面是使用匿名委托的方法解决dataView控件
                                //this.Invoke(new Action(delegate {
                                //    if (chb_NotUpdateRecvToDataGridView.Checked == false)
                                //    {
                                //       dataGridView1.Rows.Add(DGVD.Index.ToString(), DGVD.TransferDir, DGVD.OperateTime, DGVD.IDType, DGVD.DataType, DGVD.FrameID.ToString("X").PadLeft(8, '0'), DGVD.DataLength.ToString(), DGVD.Data);
                                //       if (dataGridView1.RowCount >= 2)
                                //       {
                                //           dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;
                                //       }
                                //    }
                                //    else { }
                                //}));
                                if (chb_NotUpdateRecvToDataGridView.Checked == false)
                                {
                                    
                                    sb.Append(DGVD.Index.ToString().PadRight(8, ' ') + "    " + DGVD.TransferDir + "    " +
                                                            DGVD.OperateTime + "   " + DGVD.IDType + "      " + DGVD.DataType + "     " +
                                                            DGVD.FrameID.ToString("X").PadLeft(8, '0') + "      " + DGVD.DataLength.ToString() + "    " + DGVD.Data + "\r\n");
                                }
                                else
                                {
                                    DGVD.Index--;
                                }
                                    //txb_DataShow.AppendText(sb.ToString());
                                //sb.Clear();
                                //txb_DataShow.AppendText(DGVD.Index.ToString().PadRight(8, ' ') + "    " + DGVD.TransferDir + "    " +
                                //                        DGVD.OperateTime + "   " + DGVD.IDType + "      " + DGVD.DataType + "     " +
                                //                        DGVD.FrameID.ToString("X").PadLeft(8, '0') + "      " + DGVD.DataLength.ToString() + "    " + DGVD.Data + "\t\n\t\n");
                                //txb_DataShow.AppendText("\t\n");
                                                        break;
                            default:
                                break;
                        }
                        CR.pRead = (UInt16)(CR.pRead + CR.MinLen);
                        CR.pRead %= CR.MaxLength;
                    }
                    //else
                    //{
                    //    CR.pRead++;
                    //    CR.pRead %= CR.MaxLength;
                    //}
                }
                else
                {
                    CR.pRead++;
                    CR.pRead %= CR.MaxLength;
                }

            } while ((((CR.pWrite + CR.MaxLength) - CR.pRead) % CR.MaxLength) >= CR.MinLen);
            
        }
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)  // 串口接收事件----关键型处理函数
        {
            int n = serialPort1.BytesToRead;
            if (CR.pWrite + n > CR.MaxLength)
            {
                serialPort1.Read(CR.ComRecvBuf, CR.pWrite, CR.MaxLength - CR.pWrite);
                serialPort1.Read(CR.ComRecvBuf, 0, CR.pWrite + n - CR.MaxLength);
            }
            else
            {
                serialPort1.Read(CR.ComRecvBuf, CR.pWrite, n);
            }
            CR.pWrite = (UInt16)(CR.pWrite + n);
            CR.pWrite %= CR.MaxLength;
            //if ((((CR.pWrite + CR.MaxLength) - CR.pRead) % CR.MaxLength) >= CR.MinLen)
                ComProcess();
            {
                txb_DataShow.AppendText(sb.ToString());
                sb.Clear();
            }
        }
       

        /***注意：下面函数被所有关于ID的txb引用了，方法是：选中所有的Txb控件后，再事件中选择。这样就可以到一个了！**/
        private void txb_FilterID0_KeyPress(object sender, KeyPressEventArgs e)
        {
            // 下面函数表示只能输入：数字/删除/和“ABCDEFabcdef”
            if ( !(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8
                 && e.KeyChar != 'A' && e.KeyChar != 'B' && e.KeyChar != 'C' && e.KeyChar != 'D' && e.KeyChar != 'E' && e.KeyChar != 'F'
                 && e.KeyChar != 'a' && e.KeyChar != 'b' && e.KeyChar != 'c' && e.KeyChar != 'd' && e.KeyChar != 'e' && e.KeyChar != 'f' )
            {
                e.Handled = true;  // 取消
            }
        }

        private void txb_MainSendCycleTime0_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ( !(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8 )
            {
                e.Handled = true;  // 取消
            }
        }

        private void txb_MainSendData0_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8 && e.KeyChar != ' '
                && e.KeyChar != 'A' && e.KeyChar != 'B' && e.KeyChar != 'C' && e.KeyChar != 'D' && e.KeyChar != 'E' && e.KeyChar != 'F'
                && e.KeyChar != 'a' && e.KeyChar != 'b' && e.KeyChar != 'c' && e.KeyChar != 'd' && e.KeyChar != 'e' && e.KeyChar != 'f')
            {
                e.Handled = true;  // 取消
            }
        }

        private void txb_MainSendData0_TextChanged(object sender, EventArgs e)
        {
        }

        private void btn_MainSend0_Click(object sender, EventArgs e)  // 可发送所有的函数！
        {
            string SendData = string.Empty;
            byte[] CANDataBuf = new byte[16];  // 注意数据可能越界，所以比较大一点！
            int j = 0;  // 用于存放数组的下标
            int toSendLen = 0;  // 
            Button myButton;
            System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
            byte TagIndex = 0;

            try
            {
                myButton = (Button)sender;
                TagIndex = Convert.ToByte(myButton.Tag);
            }
            catch 
            { 

            }

            try
            {
                myTimer = (System.Windows.Forms.Timer)sender;
                TagIndex = Convert.ToByte(myTimer.Tag);
            }
            catch { }

            Button MainSendCycle = pl_MainSend.Controls["btn_MainSendCycle" + TagIndex.ToString()] as Button;
            Button MainCycleSendCancle = pl_MainSend.Controls["btn_MainCycleSendCancle" + TagIndex.ToString()] as Button;


            ComboBox cmbIDType = pl_MainSend.Controls["cmb_MainSendIDType" + TagIndex.ToString()] as ComboBox;
            ComboBox cmbDataType = pl_MainSend.Controls["cmb_MainSendDataType" + TagIndex.ToString()] as ComboBox;
            TextBox textID = pl_MainSend.Controls["txb_MainSendID" + TagIndex.ToString()] as TextBox;
            TextBox textData = pl_MainSend.Controls["txb_MainSendData" + TagIndex.ToString()] as TextBox;
            switch(cmbIDType.Text)
            {
                case "标准帧":
                    MS.IDType = 0;
                    break;
                case "扩展帧":
                    MS.IDType = 1;
                    break;
                default:
                    break;
            }
            switch(cmbDataType.Text)
            {
                case "数据帧":
                    MS.DataType = 0;
                    break;
                case "远程帧":
                    MS.DataType = 1;
                    break;
                default:
                    break;
            }
            try
            {
               MS.ID_All  = Convert.ToUInt32( textID.Text.Substring(0,textID.Text.Length),16);
            }
            catch
            {
                MessageBox.Show("错误xxx：滤波器ID错误，只能输入十六进制数字", "提示");
                myTimer.Enabled = false;
                return;
            }
            try
            {
                SendData = textData.Text + " ";  // 处理函数
                for (int i = 0; i < (SendData.Length - 1); ) // 减1处理，防止越界。
                {
                    if (SendData[i] == ' ' && SendData[i + 1] == ' ')   // 连续两个空格
                    {
                        i = i + 2;  // 移动两个指针，然后继续扫描
                    }
                    else if (SendData[i] == ' ' && SendData[i + 1] != ' ')  // 空格+字符
                    {
                        i = i + 1;  // 移动一个指针，然后继续扫描
                    }
                    else if (SendData[i] != ' ' && SendData[i + 1] == ' ')  // 字符+空格
                    {
                        //     SendDataList.Add(SendData.Substring(i, 1));
                        CANDataBuf[j] = (byte)(Convert.ToInt32(SendData.Substring(i, 1), 16));
                        toSendLen = toSendLen + 1;
                        j = j + 1;
                        i = i + 2;   //显然这是一个单个字符，这个单个字符就是需要的数据
                    }
                    else if (SendData[i] != ' ' && SendData[i + 1] != ' ')  // 字符+字符
                    {
                        CANDataBuf[j] = (byte)(Convert.ToInt32(SendData.Substring(i, 2), 16));
                        toSendLen = toSendLen + 1;
                        j = j + 1;
                        i = i + 2;
                    }
                }
                if (toSendLen <= 8)
                {
                    MS.DataLength = (byte)toSendLen;
                    if( j < 8 )
                    {
                        do
                        {
                            CANDataBuf[j] = 0;
                            j++;
                        } while (j < 8);
                    }
                    else
                    {
                    }
                    /*********** 更新发送寄存器，没有数据都设置为0 *******/
                    MS.TDLR_L_18  = CANDataBuf[0];
                    MS.TDLR_ML_17 = CANDataBuf[1];
                    MS.TDLR_MH_16 = CANDataBuf[2];
                    MS.TDLR_H_15  = CANDataBuf[3];
                    MS.TDHR_L_14  = CANDataBuf[4];
                    MS.TDHR_ML_13 = CANDataBuf[5];
                    MS.TDHR_MH_12 = CANDataBuf[6];
                    MS.TDHR_H_11  = CANDataBuf[7];
                }
                else
                {
                    myTimer.Enabled = false;
                    MainSendCycle.BackColor = Color.Transparent;
                    MainCycleSendCancle.BackColor = Color.LightSkyBlue;
                    MessageBox.Show("错误xxx：发送数据"+TagIndex.ToString()+"超出长度，最多只能是8个数据", "提示");
                    
                    return;
                }
            }
            catch
            {
                myTimer.Enabled = false;
                MainSendCycle.BackColor = Color.Transparent;
                MainCycleSendCancle.BackColor = Color.LightSkyBlue;
                MessageBox.Show("错误xxx：滤波器ID错误，只能输入十六进制数字", "提示");
                return;
            }

            CANMainSendData( sender );
               
        }

        public void CANMainSendData( object sender )  // 更新数组，发送程序！同时更新DataGrid控件
        {
            System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
            byte TagIndex = 0;
            try
            {
                myTimer = (System.Windows.Forms.Timer)sender;
                TagIndex = Convert.ToByte(myTimer.Tag);
            }
            catch {
            //    MessageBox.Show("错误xxx：","");
            }

            Button MainSendCycle = pl_MainSend.Controls["btn_MainSendCycle" + TagIndex.ToString()] as Button;
            Button MainCycleSendCancle = pl_MainSend.Controls["btn_MainCycleSendCancle" + TagIndex.ToString()] as Button;

            {
                MS.TIR = 0;
                switch( MS.IDType )
                {
                    case 0:  // 标准帧
                        MS.TIR |= (UInt32)(MS.ID_All << 21);
                        MS.TIR &= ~(UInt32)(1 << 2);
                        if(MS.ID_All>0x7FF)
                        {
                            myTimer.Enabled = false;
                            MainSendCycle.BackColor = Color.Transparent;
                            MainCycleSendCancle.BackColor = Color.LightSkyBlue;
                            MessageBox.Show("错误xxx:标准帧下,帧ID文本框 " + TagIndex.ToString() + "最大值为0x7FF", "提示");
                            return;
                        }
                        else { }
                        break;
                    case 1:  // 扩展帧
                        MS.TIR |= (UInt32)(MS.ID_All << 3);
                        MS.TIR |= (UInt32)(1 << 2);
                        if (MS.ID_All > 0x1FFFFFFF)
                        {
                            myTimer.Enabled = false;
                            MainSendCycle.BackColor = Color.Transparent;
                            MainCycleSendCancle.BackColor = Color.LightSkyBlue;
                            MessageBox.Show("错误xxx:扩准帧下,帧ID文本框 " + TagIndex.ToString() + "最大值为0x1FFFFFFF", "提示");
                            return;
                        }
                        else { }
                        break;
                    default:
                        break;
                }
                switch( MS.DataType )
                { 
                    case 0:  // 数据帧
                        MS.TIR &= ~(UInt32)(1 << 1);
                        break;
                    case 1:  // 远程帧
                        MS.TIR |= (UInt32)(1 << 1);
                        break;
                    default:
                        break;
                }

                MS.TIR |= (UInt32)(1 << 0);  // 置位发送命令，实际中可能不需要！

                MS.TIR_H_3  = (byte)(MS.TIR >> 24);
                MS.TIR_MH_4 = (byte)(MS.TIR >> 16);
                MS.TIR_ML_5 = (byte)(MS.TIR >> 8);
                MS.TIR_L_6  = (byte)(MS.TIR);
            }

            {
                MS.TDTR = 0;
                MS.TDTR     |= MS.DataLength;
                MS.TDTR_H_7  = (byte)(MS.TDTR >> 24);
                MS.TDTR_MH_8 = (byte)(MS.TDTR >> 16);
                MS.TDTR_ML_9 = (byte)(MS.TDTR >>  8);
                MS.TDTR_L_10 = (byte)(MS.TDTR );
            }

            CANMainSendData_Array[0]  = MS.SendHead0_0;
            CANMainSendData_Array[1]  = MS.SendHead1_1;
            CANMainSendData_Array[2]  = MS.FuntCode_2;
            CANMainSendData_Array[3]  = MS.TIR_H_3;
            CANMainSendData_Array[4]  = MS.TIR_MH_4;
            CANMainSendData_Array[5]  = MS.TIR_ML_5;
            CANMainSendData_Array[6]  = MS.TIR_L_6;
            CANMainSendData_Array[7]  = MS.TDTR_H_7;
            CANMainSendData_Array[8]  = MS.TDTR_MH_8;
            CANMainSendData_Array[9]  = MS.TDTR_ML_9;
            CANMainSendData_Array[10] = MS.TDTR_L_10;
            CANMainSendData_Array[11] = MS.TDHR_H_11;
            CANMainSendData_Array[12] = MS.TDHR_MH_12;
            CANMainSendData_Array[13] = MS.TDHR_ML_13;
            CANMainSendData_Array[14] = MS.TDHR_L_14;
            CANMainSendData_Array[15] = MS.TDLR_H_15;
            CANMainSendData_Array[16] = MS.TDLR_MH_16;
            CANMainSendData_Array[17] = MS.TDLR_ML_17;
            CANMainSendData_Array[18] = MS.TDLR_L_18;

            MS.Sum_28 = GetSumForCommand(CANMainSendData_Array);

            CANMainSendData_Array[28] = MS.Sum_28;
            CANMainSendData_Array[29] = MS.Tail_29;

            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(CANMainSendData_Array, 0, 30); // 从0开始，发送30个数据
                /************** ↓ 更新dataView控件 ↓ ****************/
                if(chb_NotUpdateDataGrid.Checked == true)
                {

                }
                else
                {
                    DGVD.Index++;
                    DGVD.TransferDir = "发送";
                    DGVD.OperateTime = DateTime.Now.ToString("yy-MM-dd HH:mm:ss:f");
                    switch(MS.IDType)
                    {
                        case 0:
                            DGVD.IDType = "标准帧";
                            break;
                        case 1:
                            DGVD.IDType = "扩展帧";
                            break;
                        default:
                            break;
                    }
                    switch(MS.DataType)
                    {
                        case 0:
                            DGVD.DataType = "数据帧";
                            break;
                        case 1:
                            DGVD.DataType = "远程帧";
                            break;
                        default:
                            break;
                    }
                    DGVD.FrameID = MS.ID_All;
                    DGVD.DataLength = MS.DataLength;
                    DGVD.Data = string.Empty;
                    if (DGVD.DataType == "远程帧")
                    {
                        DGVD.DataLength = 0;
                        DGVD.Data = "--";
                    }
                    else
                    {
                        switch (MS.DataLength)
                        {
                            case 0:
                                DGVD.Data = string.Empty;
                                break;
                            case 1:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            case 2:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            case 3:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_MH_16.ToString("X").PadLeft(2, '0');
                                break;
                            case 4:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_MH_16.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_H_15.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            case 5:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_MH_16.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_H_15.ToString("X").PadLeft(2, '0') + ' '
                                          + MS.TDHR_L_14.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            case 6:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_MH_16.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_H_15.ToString("X").PadLeft(2, '0') + ' '
                                          + MS.TDHR_L_14.ToString("X").PadLeft(2, '0') + ' ' + MS.TDHR_ML_13.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            case 7:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_MH_16.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_H_15.ToString("X").PadLeft(2, '0') + ' '
                                          + MS.TDHR_L_14.ToString("X").PadLeft(2, '0') + ' ' + MS.TDHR_ML_13.ToString("X").PadLeft(2, '0') + ' ' + MS.TDHR_MH_12.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            case 8:
                                DGVD.Data = MS.TDLR_L_18.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_ML_17.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_MH_16.ToString("X").PadLeft(2, '0') + ' ' + MS.TDLR_H_15.ToString("X").PadLeft(2, '0') + ' '
                                          + MS.TDHR_L_14.ToString("X").PadLeft(2, '0') + ' ' + MS.TDHR_ML_13.ToString("X").PadLeft(2, '0') + ' ' + MS.TDHR_MH_12.ToString("X").PadLeft(2, '0') + ' ' + MS.TDHR_H_11.ToString("X").PadLeft(2, '0') + ' ';
                                break;
                            default:
                                break;
                        }
                    }

                    if( chb_NotUpdateDataGrid.Checked == false )
                    {
                        sb.Append(DGVD.Index.ToString().PadRight(8, ' ') + "    " + DGVD.TransferDir + "    " +
                                                            DGVD.OperateTime + "   " + DGVD.IDType + "      " + DGVD.DataType + "     " +
                                                            DGVD.FrameID.ToString("X").PadLeft(8, '0') + "      " + DGVD.DataLength.ToString() + "    " + DGVD.Data + "\r\n");
                    }
                    else
                    {
                        DGVD.Index--;
                    }
                        //dataGridView1.Rows.Add(DGVD.Index.ToString(),DGVD.TransferDir,DGVD.OperateTime,DGVD.IDType,DGVD.DataType,DGVD.FrameID.ToString("X").PadLeft(8, '0'),DGVD.DataLength.ToString(),DGVD.Data);
                        //if (dataGridView1.RowCount >= 2)
                        //{
                        //    dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 2;
                        //}
                    }
                /************** ↑ 更新dataView控件 ↑ ****************/
            }
            else
            {
                myTimer.Enabled = false;
                MainSendCycle.BackColor = Color.Transparent;
                MainCycleSendCancle.BackColor = Color.LightSkyBlue;
                MessageBox.Show("错误xxx：串口没有打开", "提示");
                return;
            }
        }
/************************* ↓ 主发送循环整件 ↓ **********************************/
        private void btn_MainSendCycle0_Click(object sender, EventArgs e)  // 循环发送
        {
            int MainSendTimeInterval = 0;
            Button myButton = (Button)sender;
            byte tagIndex = Convert.ToByte(myButton.Tag);


            TextBox TimerInterval = pl_MainSend.Controls["txb_MainSendCycleTime" + tagIndex.ToString()] as TextBox;
            Button CancelButton = pl_MainSend.Controls["btn_MainCycleSendCancle" + tagIndex.ToString()] as Button;

            myButton.BackColor = Color.LightSkyBlue;
            CancelButton.BackColor = Color.Transparent;

            try
            {
                MainSendTimeInterval = Convert.ToInt32(TimerInterval.Text.Substring(0, TimerInterval.Text.Length), 10);
            }
            catch
            {
                CancelButton.BackColor = Color.LightSkyBlue;
                myButton.BackColor = Color.Transparent;
                switch(tagIndex)
                {
                    case 0:
                        tmr_MainSend0.Enabled = false;
                        break;
                    case 1:
                        tmr_MainSend1.Enabled = false;
                        break;
                    case 2:
                        tmr_MainSend2.Enabled = false;
                        break;
                    case 3:
                        tmr_MainSend3.Enabled = false;
                        break;
                    case 4:
                        tmr_MainSend4.Enabled = false;
                        break;
                    case 5:
                        tmr_MainSend5.Enabled = false;
                        break;
                }
                MessageBox.Show("错误xxx:文本框 "+ tagIndex.ToString() +" 输入不正确","提示");
                return;
            }
            if ( MainSendTimeInterval < 100)
            {
                CancelButton.BackColor = Color.LightSkyBlue;
                myButton.BackColor = Color.Transparent;
                switch (tagIndex)
                {
                    case 0:
                        tmr_MainSend0.Enabled = false;
                        break;
                    case 1:
                        tmr_MainSend1.Enabled = false;
                        break;
                    case 2:
                        tmr_MainSend2.Enabled = false;
                        break;
                    case 3:
                        tmr_MainSend3.Enabled = false;
                        break;
                    case 4:
                        tmr_MainSend4.Enabled = false;
                        break;
                    case 5:
                        tmr_MainSend5.Enabled = false;
                        break;
                }
                MessageBox.Show("错误xxx:文本框 " + tagIndex.ToString() + " 输入的时间不能小于100ms", "提示");
                return;
            }
            switch (tagIndex)
            {
                case 0:
                    tmr_MainSend0.Interval = (int)MainSendTimeInterval;
                    tmr_MainSend0.Enabled = Enabled;
                    break;
                case 1:
                    tmr_MainSend1.Interval = (int)MainSendTimeInterval;
                    tmr_MainSend1.Enabled = Enabled;
                    break;
                case 2:
                    tmr_MainSend2.Interval = (int)MainSendTimeInterval;
                    tmr_MainSend2.Enabled = Enabled;
                    break;
                case 3:
                    tmr_MainSend3.Interval = (int)MainSendTimeInterval;
                    tmr_MainSend3.Enabled = Enabled;
                    break;
                case 4:
                    tmr_MainSend4.Interval = (int)MainSendTimeInterval;
                    tmr_MainSend4.Enabled = Enabled;
                    break;
                case 5:
                    tmr_MainSend5.Interval = (int)MainSendTimeInterval;
                    tmr_MainSend5.Enabled = Enabled;
                    break;
            }

        }
        private void tmr_MainSend0_Tick(object sender, EventArgs e)
        {
            int MainSendTimeInterval = 0;
            System.Windows.Forms.Timer myTimer = (System.Windows.Forms.Timer)sender;
            byte tagIndex = Convert.ToByte(myTimer.Tag);
            TextBox TimerInterval = pl_MainSend.Controls["txb_MainSendCycleTime" + tagIndex.ToString()] as TextBox;

            Button mainSendCycle = pl_MainSend.Controls["btn_MainSendCycle" + tagIndex.ToString()] as Button;
            Button mainSendCycleCancel = pl_MainSend.Controls["btn_MainCycleSendCancle" + tagIndex.ToString()] as Button;

            try
            {
                MainSendTimeInterval = Convert.ToInt32(TimerInterval.Text.Substring(0, TimerInterval.Text.Length), 10);
            }
            catch
            {
                myTimer.Enabled = false;
                mainSendCycle.BackColor = Color.Transparent;
                mainSendCycleCancel.BackColor = Color.LightSkyBlue;
                MessageBox.Show("错误xxx:文本框 " + tagIndex.ToString() + " 输入不正确", "提示");
                return;
            }
            if (MainSendTimeInterval < 100)
            {
                myTimer.Enabled = false;
                mainSendCycle.BackColor = Color.Transparent;
                mainSendCycleCancel.BackColor = Color.LightSkyBlue;
                MessageBox.Show("错误xxx:文本框 " + tagIndex.ToString() + " 输入的时间不能小于100ms", "提示");
                return;
            }

            switch (tagIndex)
            {
                case 0:
                    tmr_MainSend0.Interval = (int)MainSendTimeInterval;
                    break;
                case 1:
                    tmr_MainSend1.Interval = (int)MainSendTimeInterval;
                    break;
                case 2:
                    tmr_MainSend2.Interval = (int)MainSendTimeInterval;
                    break;
                case 3:
                    tmr_MainSend3.Interval = (int)MainSendTimeInterval;
                    break;
                case 4:
                    tmr_MainSend4.Interval = (int)MainSendTimeInterval;
                    break;
                case 5:
                    tmr_MainSend5.Interval = (int)MainSendTimeInterval;
                    break;
            }

            btn_MainSend0_Click(sender, e);
        }
        private void btn_MainCycleSendCancle0_Click(object sender, EventArgs e) // 循环停止
        {
            Button myButton = (Button)sender;
            byte tagIndex = Convert.ToByte(myButton.Tag);
            Button MainSendCycle = pl_MainSend.Controls["btn_MainSendCycle" + tagIndex.ToString()] as Button;

            myButton.BackColor = Color.LightSkyBlue;
            MainSendCycle.BackColor = Color.Transparent;

            switch(tagIndex)
            {
                case 0:
                    tmr_MainSend0.Enabled = false;
                    break;
                case 1:
                    tmr_MainSend1.Enabled = false;
                    break;
                case 2:
                    tmr_MainSend2.Enabled = false;
                    break;
                case 3:
                    tmr_MainSend3.Enabled = false;
                    break;
                case 4:
                    tmr_MainSend4.Enabled = false;
                    break;
                case 5:
                    tmr_MainSend5.Enabled = false;
                    break;
                default: break;
            }

        }

/************************* ↑ 主发送循环整件 ↑ **********************************/
        private void btn_ClearData_Click(object sender, EventArgs e)
        {
            //dataGridView1.Rows.Clear();
            txb_DataShow.Clear();
            sb.Clear();
            DGVD.Index = 0;
        }

        private void btn_SetFilter0_Click(object sender, EventArgs e)
        {
        }

/************************* ↓ 滤波器设置 ↓ **********************************/
        void UpdateFilterSetCommand_Array()
        {
            FilterSetCommand_Array[0] = FS.SendHead0;
            FilterSetCommand_Array[1] = FS.SendHead1;
            FilterSetCommand_Array[2] = FS.FunctionCode;
            FilterSetCommand_Array[3] = FS.FilterIndex;
            FilterSetCommand_Array[4] = FS.OpenFilter;
            FilterSetCommand_Array[5] = FS.FilterID_H;
            FilterSetCommand_Array[6] = FS.FilterID_MH;
            FilterSetCommand_Array[7] = FS.FilterID_ML;
            FilterSetCommand_Array[8] = FS.FilterID_L;
            FilterSetCommand_Array[9] = FS.FilterMask_H;
            FilterSetCommand_Array[10] = FS.FilterMask_MH;
            FilterSetCommand_Array[11] = FS.FilterMask_ML;
            FilterSetCommand_Array[12] = FS.FilterMask_L;

            FS.Sum = GetSumForCommand(FilterSetCommand_Array);
            FilterSetCommand_Array[28] = FS.Sum;
            FilterSetCommand_Array[29] = FS.SendTail;

        }
        public byte SingleFilterSet_SubFunction(byte TagIndex)
        {
            UInt32 FilterID = 0;
            UInt32 FilterMask = 0;
            TextBox txb_FilterID = pl_FilterSet.Controls["txb_FilterID" + TagIndex.ToString()] as TextBox;
            TextBox txb_FilterMask = pl_FilterSet.Controls["txb_FilterMASK" + TagIndex.ToString()] as TextBox;
            try
            {
                FilterID = Convert.ToUInt32(txb_FilterID.Text.Substring(0, txb_FilterID.Text.Length), 16);
            }
            catch
            {
                MessageBox.Show("错误xxx：滤波器ID错误，只能输入十六进制数字，请检查", "提示");
                return 0;
            }
            try
            {
                FilterMask = Convert.ToUInt32(txb_FilterMask.Text.Substring(0, txb_FilterMask.Text.Length), 16);
            }
            catch
            {
                MessageBox.Show("错误xxx：滤波器MASK错误，只能输入十六进制数字，请检查", "提示");
                return 0;
            }

            FS.OpenFilter = 1;  // 打开Filter指令在这里定义！
            FS.FilterIndex = TagIndex;
            /********************************************************************************************/
            FS.FilterID_H = (byte)(FilterID >> 24);
            FS.FilterID_MH = (byte)(FilterID >> 16);
            FS.FilterID_ML = (byte)(FilterID >> 8);
            FS.FilterID_L = (byte)(FilterID);
            FS.FilterMask_H = (byte)(FilterMask >> 24);
            FS.FilterMask_MH = (byte)(FilterMask >> 16);
            FS.FilterMask_ML = (byte)(FilterMask >> 8);
            FS.FilterMask_L = (byte)(FilterMask);
            UpdateFilterSetCommand_Array();
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(FilterSetCommand_Array, 0, 30); // 发送30个数据
            }
            else
            {
                MessageBox.Show("错误xxx:请打开对应串口", "提示");
                return 0;
            }
            return 1;
        }
        private void SingleFilterSet(object sender, EventArgs e)
        {
            Button btn_SingleFilterSet = (Button)sender;
            byte tagIndex = Convert.ToByte(btn_SingleFilterSet.Tag);
            Button btn_SingleFilterCancel = pl_FilterSet.Controls["btn_CancelFilter" + tagIndex.ToString()] as Button;
            if(SingleFilterSet_SubFunction(tagIndex) == 1) // 设置成功
            {
                btn_SingleFilterSet.BackColor = Color.LightSkyBlue;
                btn_SingleFilterCancel.BackColor = Color.Transparent;
            }
            else
            { }
        }

        public byte SingleFilterCancel_SubFunction(byte TagIndex)
        {
            FS.OpenFilter = 0;   // 关闭指令
            FS.FilterIndex = TagIndex; // 对应Fliter号
            UpdateFilterSetCommand_Array();
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(FilterSetCommand_Array, 0, 30); // 发送30个数据
            }
            else
            {
                MessageBox.Show("错误xxx:请打开对应串口", "提示");
                return 0;
            }
            return 1;
        }
        private void SingleFilterCancel(object sender, EventArgs e)  // 主要就是获取button
        {
            Button btn_SingleFilterCancel = (Button)sender;
            byte tagIndex = Convert.ToByte(btn_SingleFilterCancel.Tag);
            Button btn_SingleFilterSet = pl_FilterSet.Controls["btn_SetFilter" + tagIndex.ToString()] as Button;
            if (SingleFilterCancel_SubFunction(tagIndex) == 1) // 设置成功
            {
              btn_SingleFilterCancel.BackColor = Color.LightSkyBlue;
              btn_SingleFilterSet.BackColor = Color.Transparent;
            }
            else
            { }
        }

        private void AllFliterOperation(object sender, EventArgs e)
        {
            Button btn_AllFliterOperation = (Button)sender;
            byte tagIndex = Convert.ToByte(btn_AllFliterOperation.Tag);
            switch(tagIndex)
            {
                case 0: // 取消
                    for (byte temp = 0; temp <= 13;temp++ )
                    {
                        if (SingleFilterCancel_SubFunction(temp) == 0)
                        {
                            break;
                        }
                        else
                        {
                            Button btn_SingleFilterSet = pl_FilterSet.Controls["btn_SetFilter" + temp.ToString()] as Button;
                            Button btn_SingleFilterCancel = pl_FilterSet.Controls["btn_CancelFilter" + temp.ToString()] as Button;
                            btn_SingleFilterCancel.BackColor = Color.LightSkyBlue;
                            btn_SingleFilterSet.BackColor = Color.Transparent;
                        }
                    }
                  break;
                case 1: // 设置
                        for (byte temp = 0; temp <= 13; temp++)
                        {
                            if (SingleFilterSet_SubFunction(temp) == 0)
                            {
                                break;
                            }
                            else
                            {
                                Button btn_SingleFilterSet = pl_FilterSet.Controls["btn_SetFilter" + temp.ToString()] as Button;
                                Button btn_SingleFilterCancel = pl_FilterSet.Controls["btn_CancelFilter" + temp.ToString()] as Button;
                                btn_SingleFilterSet.BackColor = Color.LightSkyBlue;
                                btn_SingleFilterCancel.BackColor = Color.Transparent;
                            }
                        }
                    break;
                default:
                    break;
            }
        }

        

/************************* ↑ 滤波器设置 ↑ **********************************/

/************************* ↓ 批量发送窗口 ↓ **********************************/
        static Send_Class SB = new Send_Class();
        byte[] CANSendBatchData_Array = new byte[30];
        public byte SendBatch_SubFun( byte tagIndex ) // 两个功能：第一发送数据，第二：增加到GridView
        {
            string SendData = string.Empty;
            byte[] CANDataBuf = new byte[16];
            int j = 0;  // 用于存放数组的下标
            int toSendLen = 0;  // 


            ComboBox cmb_IDType = pl_SendBatch.Controls["cmb_SendIDType" + tagIndex.ToString()] as ComboBox;
            ComboBox cmb_DataType = pl_SendBatch.Controls["chb_SendDataType" + tagIndex.ToString()] as ComboBox;
            TextBox txb_ID = pl_SendBatch.Controls["txb_SendID" + tagIndex.ToString()] as TextBox;
            TextBox txb_Data = pl_SendBatch.Controls["txb_SendData" + tagIndex.ToString()] as TextBox;

            try
            {
                SB.ID_All = Convert.ToUInt32(txb_ID.Text.Substring(0, txb_ID.Text.Length), 16);
            }
            catch
            {
                tmr_Send.Enabled = false;
                btn_SendCycle.BackColor = Color.Transparent;
                btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                MessageBox.Show("错误xxx:帧ID文本框 " + tagIndex.ToString() + " 输入错误,请检查", "提示");
                return 0;
            }
            {
                try
                {
                    SendData = txb_Data.Text + " ";  // 处理函数
                    for (int i = 0; i < (SendData.Length - 1); ) // 减1处理，防止越界。
                    {
                        if (SendData[i] == ' ' && SendData[i + 1] == ' ')   // 连续两个空格
                        {
                            i = i + 2;  // 移动两个指针，然后继续扫描
                        }
                        else if (SendData[i] == ' ' && SendData[i + 1] != ' ')  // 空格+字符
                        {
                            i = i + 1;  // 移动一个指针，然后继续扫描
                        }
                        else if (SendData[i] != ' ' && SendData[i + 1] == ' ')  // 字符+空格
                        {
                            //     SendDataList.Add(SendData.Substring(i, 1));
                            CANDataBuf[j] = (byte)(Convert.ToInt32(SendData.Substring(i, 1), 16));
                            toSendLen = toSendLen + 1;
                            j = j + 1;
                            i = i + 2;   //显然这是一个单个字符，这个单个字符就是需要的数据
                        }
                        else if (SendData[i] != ' ' && SendData[i + 1] != ' ')  // 字符+字符
                        {
                            CANDataBuf[j] = (byte)(Convert.ToInt32(SendData.Substring(i, 2), 16));
                            toSendLen = toSendLen + 1;
                            j = j + 1;
                            i = i + 2;
                        }
                    }
                    if (toSendLen <= 8)
                    {
                        SB.DataLength = (byte)toSendLen;
                        SB.TDTR = SB.DataLength;
                        if (j < 8)
                        {
                            do
                            {
                                CANDataBuf[j] = 0;
                                j++;
                            } while (j < 8);
                        }
                        else
                        {
                            // 不需要处理
                        }
                        /*********** 更新发送寄存器，没有数据都设置为0 *******/
                        SB.TDLR_L_18 = CANDataBuf[0];  // 从低到高更新寄存器
                        SB.TDLR_ML_17 = CANDataBuf[1];
                        SB.TDLR_MH_16 = CANDataBuf[2];
                        SB.TDLR_H_15 = CANDataBuf[3];
                        SB.TDHR_L_14 = CANDataBuf[4];
                        SB.TDHR_ML_13 = CANDataBuf[5];
                        SB.TDHR_MH_12 = CANDataBuf[6];
                        SB.TDHR_H_11 = CANDataBuf[7];
                    }
                    else
                    {
                        SB.DataLength = 0;
                        SB.TDTR = SB.DataLength;
                        SB.TDLR_L_18 = 0;
                        SB.TDLR_ML_17 = 0;
                        SB.TDLR_MH_16 = 0;
                        SB.TDLR_H_15 = 0;
                        SB.TDHR_L_14 = 0;
                        SB.TDHR_ML_13 = 0;
                        SB.TDHR_MH_12 = 0;
                        SB.TDHR_H_11 = 0;

                        tmr_Send.Enabled = false;
                        btn_SendCycle.BackColor = Color.Transparent;
                        btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                        MessageBox.Show("错误xxx：数据" + tagIndex.ToString() + "超出长度，最多只能是8个数据", "提示");
                        return 0;
                    }
                    SB.TDTR_H_7 = (byte)(SB.TDTR >> 24);
                    SB.TDTR_MH_8 = (byte)(SB.TDTR >> 16);
                    SB.TDTR_ML_9 = (byte)(SB.TDTR >> 8);
                    SB.TDTR_L_10 = (byte)(SB.TDTR);
                }
                catch
                {
                    tmr_Send.Enabled = false;
                    btn_SendCycle.BackColor = Color.Transparent;
                    btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                    MessageBox.Show("错误xxx：数据" + tagIndex.ToString() + "数据出错,可输入十六进制和英文空格", "提示");
                    return 0;
                }
            }
            {
                switch (cmb_IDType.Text)
                {
                    case "标准帧":
                        SB.IDType = 0;
                        SB.TIR &= ~(UInt32)(1 << 2);
                        if (SB.ID_All > 0x7FF)
                        {
                            tmr_Send.Enabled = false;
                            btn_SendCycle.BackColor = Color.Transparent;
                            btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                            MessageBox.Show("错误xxx:标准帧下,帧ID文本框 " + tagIndex.ToString() + "最大值为0x7FF", "提示");
                            return 0;
                        }
                        else { }
                        SB.TIR &= (UInt32)0x00000007;
                        SB.TIR |= (UInt32)(SB.ID_All << 21);


                        break;
                    case "扩展帧":
                        SB.IDType = 1;
                        SB.TIR |= (UInt32)(1 << 2);
                        if (SB.ID_All > 0x1FFFFFFF)
                        {
                            tmr_Send.Enabled = false;
                            btn_SendCycle.BackColor = Color.Transparent;
                            btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                            MessageBox.Show("错误xxx:扩展帧下,帧ID文本框 " + tagIndex.ToString() + "最大值为0x1FFFFFFF", "提示");
                            return 0;
                        }
                        else { }
                        SB.TIR &= (UInt32)0x00000007;
                        SB.TIR |= (UInt32)(SB.ID_All << 3);
                        break;
                    default:
                        break;
                }
                switch (cmb_DataType.Text)
                {
                    case "数据帧":
                        SB.DataType = 0;
                        SB.TIR &= ~(UInt32)(1 << 1);
                        break;
                    case "远程帧":
                        SB.DataType = 1;
                        SB.TIR |= (UInt32)(1 << 1);
                        break;
                    default:
                        break;
                }
                SB.TIR_H_3 = (byte)(SB.TIR >> 24);
                SB.TIR_MH_4 = (byte)(SB.TIR >> 16);
                SB.TIR_ML_5 = (byte)(SB.TIR >> 8);
                SB.TIR_L_6 = (byte)(SB.TIR);
            }
            { //下面为发送函数
                CANSendBatchData_Array[0] = SB.SendHead0_0;
                CANSendBatchData_Array[1] = SB.SendHead1_1;
                CANSendBatchData_Array[2] = SB.FuntCode_2;
                CANSendBatchData_Array[3] = SB.TIR_H_3;
                CANSendBatchData_Array[4] = SB.TIR_MH_4;
                CANSendBatchData_Array[5] = SB.TIR_ML_5;
                CANSendBatchData_Array[6] = SB.TIR_L_6;
                CANSendBatchData_Array[7] = SB.TDTR_H_7;
                CANSendBatchData_Array[8] = SB.TDTR_MH_8;
                CANSendBatchData_Array[9] = SB.TDTR_ML_9;
                CANSendBatchData_Array[10] = SB.TDTR_L_10;
                CANSendBatchData_Array[11] = SB.TDHR_H_11;
                CANSendBatchData_Array[12] = SB.TDHR_MH_12;
                CANSendBatchData_Array[13] = SB.TDHR_ML_13;
                CANSendBatchData_Array[14] = SB.TDHR_L_14;
                CANSendBatchData_Array[15] = SB.TDLR_H_15;
                CANSendBatchData_Array[16] = SB.TDLR_MH_16;
                CANSendBatchData_Array[17] = SB.TDLR_ML_17;
                CANSendBatchData_Array[18] = SB.TDLR_L_18;

                CANSendBatchData_Array[28] = GetSumForCommand(CANSendBatchData_Array);
                CANSendBatchData_Array[29] = SB.Tail_29;

                if(serialPort1.IsOpen == true)
                {
                    serialPort1.Write(CANSendBatchData_Array, 0, 30);
                }
                else
                {
                    tmr_Send.Enabled = false;
                    btn_SendCycle.BackColor = Color.Transparent;
                    btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                    MessageBox.Show("错误777:串口没有打开","提示");
                    return 0;
                }
            }
            { // 下面为更新dataView
             if(chb_NotUpdateDataGrid.Checked == false)
             {
                DGVD.Index++;
                DGVD.TransferDir = "发送";
                switch (SB.IDType)
                {
                    case 0:
                        DGVD.IDType = "标准帧";
                        break;
                    case 1:
                        DGVD.IDType = "扩展帧";
                        break;
                    default: break;
                }
                switch (SB.DataType)
                {
                    case 0:
                        DGVD.DataType = "数据帧";
                        break;
                    case 1:
                        DGVD.DataType = "远程帧";
                        break;
                    default: break;
                }
                DGVD.FrameID = SB.ID_All;
                DGVD.DataLength = SB.DataLength;
                {
                    DGVD.Data = string.Empty;
                    if (DGVD.DataType == "数据帧")
                    {
                        for (byte temp = 0; temp < SB.DataLength; temp++)
                        {
                            DGVD.Data += CANDataBuf[temp].ToString("X").PadLeft(2, '0') + ' ';
                        }

                    }
                    else 
                    {
                        DGVD.Data = "--";
                    }
                }
                DGVD.OperateTime = DateTime.Now.ToString("yy-MM-dd HH:mm:ss:f");

                //this.Invoke(new Action(delegate
                //{
                    //dataGridView1.Rows.Add(DGVD.Index.ToString(), DGVD.TransferDir, DGVD.OperateTime, DGVD.IDType, DGVD.DataType, DGVD.FrameID.ToString("X").PadLeft(8, '0'), DGVD.DataLength.ToString(), DGVD.Data);
                    //if (dataGridView1.RowCount >= 2)
                    //{
                    //    dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;
                    //}
                if (chb_NotUpdateDataGrid.Checked == false)
                {
                    sb.Append(DGVD.Index.ToString().PadRight(8, ' ') + "    " + DGVD.TransferDir + "    " +
                                                        DGVD.OperateTime + "   " + DGVD.IDType + "      " + DGVD.DataType + "     " +
                                                        DGVD.FrameID.ToString("X").PadLeft(8, '0') + "      " + DGVD.DataLength.ToString() + "    " + DGVD.Data + "\r\n");
                }
                else
                {
                    DGVD.Index--;
                }
              //  }));
            }
             else { };

            }
            
            return 1;
        }
        private void SendBatch(object sender, EventArgs e)  // 基于TagIndex的发送!
        {
            Button btn_SendBatch = (Button)sender;
            byte tagIndex = Convert.ToByte(btn_SendBatch.Tag);
            SendBatch_SubFun(tagIndex);
        }

        private void btn_SendCycle_Click(object sender, EventArgs e)  // 批量循环发送，只是启动定时器
        {
            int timeInterval = 0;
            try
            {
                timeInterval = Convert.ToInt32(txb_SendCycleTime.Text.Substring(0, txb_SendCycleTime.Text.Length));
            }
            catch
            {
                MessageBox.Show("错误xxx:请输入正确的十进制时间", "提示");
                return;
            }

            if(timeInterval<1000)
            {
                MessageBox.Show("警告xxx:最小时间不能小于1000ms","提示");
                return;
            }
            else { }
            tmr_Send.Interval = timeInterval;
            tmr_Send.Enabled = Enabled;
            btn_SendCycle.BackColor = Color.LightSkyBlue;
            btn_CycleSendCancle.BackColor = Color.Transparent;
        }
        private void btn_CycleSendCancle_Click(object sender, EventArgs e) // 批量发送取消，关闭定时器
        {
            tmr_Send.Enabled = false;
            btn_SendCycle.BackColor = Color.Transparent;
            btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
        }
        private void tmr_Send_Tick(object sender, EventArgs e) // 批量定时器
        {
            int timeInterval = 0;
            try
            {
                timeInterval = Convert.ToInt32(txb_SendCycleTime.Text.Substring(0, txb_SendCycleTime.Text.Length));
            }
            catch
            {
                tmr_Send.Enabled = false;
                btn_SendCycle.BackColor = Color.Transparent;
                btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                MessageBox.Show("错误xxx:请输入正确的十进制时间", "提示");
                return;
            }
            if (timeInterval < 1000)
            {
                tmr_Send.Enabled = false;
                btn_SendCycle.BackColor = Color.Transparent;
                btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                MessageBox.Show("警告xxx:最小时间不能小于1000ms", "提示");
                return;
            }
            else { }
            tmr_Send.Interval = timeInterval;
            for(byte chbIndex = 1;chbIndex<=20;chbIndex++)
            {
                CheckBox chbSend = pl_SendBatch.Controls["chb_Send" + chbIndex.ToString()] as CheckBox;
                switch(chbSend.Checked)
                {
                    case true:
                        if (SendBatch_SubFun(chbIndex) == 0)  // 表明发送失败。
                        {
                            tmr_Send.Enabled = false;
                            btn_SendCycle.BackColor = Color.Transparent;
                            btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
                            return;
                        }
                        else
                        {
                        }
                        break;
                    case false:
                        break;
                    default: break;
                }
            }
            //{ // 间隔发送，用全局变量间隔发送。// 如果扫了20次还没有结果，显然就是没有被选中的数据！
            //interval:
            //    if ((forIntervalTrasnfer >= 1) && (forIntervalTrasnfer <= 20))
            //    {
            //        scanSum++;
            //        CheckBox chbSend = pl_SendBatch.Controls["chb_Send" + forIntervalTrasnfer.ToString()] as CheckBox;
            //        if(chbSend.Checked == true)
            //        {
            //            scanSum = 0;
            //            if (SendBatch_SubFun(forIntervalTrasnfer) == 0)  // 表明发送失败。
            //            {
            //                tmr_Send.Enabled = false;
            //                btn_SendCycle.BackColor = Color.Transparent;
            //                btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
            //                scanSum = 0;
            //                forIntervalTrasnfer = 1;
            //                return;
            //            }
            //            else // 发送成功 
            //            {
            //                forIntervalTrasnfer++;
            //                if (forIntervalTrasnfer >= 21)
            //                    forIntervalTrasnfer = 1;
            //                return;
            //            }
            //        }
            //        else
            //        {
            //            forIntervalTrasnfer++;
            //            if (forIntervalTrasnfer >= 21)
            //                forIntervalTrasnfer = 1;
            //            if (scanSum >= 20) // 扫了20次，从1到20都结束了，还没有成功。
            //            {
            //                MessageBox.Show("没有选中的选项！", "提示");
            //                tmr_Send.Enabled = false;
            //                btn_SendCycle.BackColor = Color.Transparent;
            //                btn_CycleSendCancle.BackColor = Color.LightSkyBlue;
            //                scanSum = 0;
            //                forIntervalTrasnfer = 1;
            //            }
            //            else { }
            //            goto interval;   
            //        }
            //    }
            //    else
            //    {
            //        forIntervalTrasnfer = 1;
            //        scanSum = 0;
            //        goto interval;  
            //    }
            //}
        }
/************************* ↑ 批量发送窗口 ↑ **********************************/
/************************* ↓ 常规功能设置 ↓ **********************************/
        private void CalculatorBuadrate(object sender, EventArgs e)  // 计算函数
        {
            byte tBS1 = 0;
            byte tBS2 = 0;
            UInt16 BRP = 0;
            UInt32 baudrateCalculateValue = 0;
            float sampleValue = 0;
            try
            {
                tBS1 = Convert.ToByte(cmb_tBS1.Text.Substring(0,cmb_tBS1.Text.Length));
                tBS2 = Convert.ToByte(cmb_tBS2.Text.Substring(0,cmb_tBS2.Text.Length));
                BRP = Convert.ToUInt16(txb_BRPValue.Text.Substring(0,txb_BRPValue.Text.Length));
                baudrateCalculateValue = (UInt32)(36000000 /((BRP+1)*(tBS1+tBS2+3)) );
                if (baudrateCalculateValue <= 1000000)
                    txb_CalculateCANBaudrate.Text = baudrateCalculateValue.ToString() + " bps";
                else
                    txb_CalculateCANBaudrate.Text = "Error:不在有效范围!";

                sampleValue = ((1+(float)tBS1)/(1+(float)tBS1+(float)tBS2))*100;
                txb_SamleValue.Text = float.Parse(sampleValue.ToString("G3")).ToString()+"%";
            }
            catch
            {
                txb_CalculateCANBaudrate.Text = "Error:请设置正确的值!";
            }
        }

        private void btn_SerialPortOperate(object sender, EventArgs e)
        {
            Button btn_SerialPortOperate = (Button)sender;
            switch (btn_SerialPortOperate.Tag.ToString())
            {
                case "Open/Close":  // 打开/关闭串口
                    switch (btn_SerialPortOpen.Text)
                    {
                        case "打开串口":
                            try
                            {
                                string ComPortName = null;   // 我总感觉下面的总可以优化
                                { // 找串口号
                                    if (cmb_SerialPortIndex.Text[4] == ' ')  // COMn 形式
                                        ComPortName = cmb_SerialPortIndex.Text.Substring(0, 4);  // 表示从0开始，获取4个字符！
                                    else if (cmb_SerialPortIndex.Text[5] == ' ')  // COMnn 形式
                                        ComPortName = cmb_SerialPortIndex.Text.Substring(0, 5);
                                    else if (cmb_SerialPortIndex.Text[6] == ' ')  // COMnnn 形式
                                        ComPortName = cmb_SerialPortIndex.Text.Substring(0, 6);
                                    else if (cmb_SerialPortIndex.Text[7] == ' ')  // COMnnnn 形式
                                        ComPortName = cmb_SerialPortIndex.Text.Substring(0, 7);
                                }
                                serialPort1.PortName = ComPortName;
                                serialPort1.Open();
                                btn_SerialPortOpen.Text = "关闭串口";
                                cmb_SerialPortIndex.Enabled = false;
                                btn_SerialPortRefresh.Enabled = false;
                                lablel_SerialPortStatus.Text = "串口状态:已打开";
                            }
                            catch
                            {
                                MessageBox.Show("错误001:串口打开失败,请检查", "提示");
                            }
                            break;
                        case "关闭串口":
                            try
                            {
                                serialPort1.Close();
                                btn_SerialPortOpen.Text = "打开串口";
                                cmb_SerialPortIndex.Enabled = true;
                                btn_SerialPortRefresh.Enabled = true;
                                lablel_SerialPortStatus.Text = "串口状态:已关闭";
                            }
                            catch
                            {
                                MessageBox.Show("错误002:串口关闭失败,请检查", "提示");
                            }
                            break;
                        default: break;
                    }
                    break;
                case "Fresh":  // 刷新串口
                    SerialPortFresh();
                    break;
                default:
                    break;
            }
        }

        private void chb_CustomEnable_CheckedChanged(object sender, EventArgs e)
        {
            switch(chb_CustomEnable.Checked)
            {
                case true:
                    cmb_tBS1.Enabled = true;
                    cmb_tBS2.Enabled = true;
                    txb_BRPValue.Enabled = true;
                    txb_CalculateCANBaudrate.Enabled = true;
                    cmb_Baudrate.Enabled = false;
                    break;
                case false:
                    cmb_tBS1.Enabled = false;
                    cmb_tBS2.Enabled = false;
                    txb_BRPValue.Enabled = false;
                    txb_CalculateCANBaudrate.Enabled = false;
                    cmb_Baudrate.Enabled = true;
                    break;
                default: break;
            }
            
        }

        private void btn_BasicSet_Click(object sender, EventArgs e)  // 功能设置
        {
            switch (cmb_WorkFunSet.Text)
            {
                case"正常模式":
                    BFS.RunMode = 0;
                    break;
                case"环回模式":
                    BFS.RunMode = 1;
                    break;
                case"静默模式":
                    BFS.RunMode = 2;
                    break;
                case"环回静默模式":
                    BFS.RunMode = 3;
                    break;
                default:
                    break;
            }
            switch(chb_AtuoRetransfer.Checked)
            {
                case true: // 允许自动重发
                    BFS.ForbidAutomaticReSend = 0;  // 自动重发
                    break;
                case false:
                    BFS.ForbidAutomaticReSend = 1;  // 禁止自动重发
                    break;
                default: break;
            }
            switch(chb_CustomEnable.Checked)
            {
                case true: // 自定义波特率
                    {
                        try 
                        {
                            BFS.tBS1 = Convert.ToByte(cmb_tBS1.Text.Substring(0, cmb_tBS1.Text.Length));
                            BFS.tBS2 = Convert.ToByte(cmb_tBS2.Text.Substring(0, cmb_tBS2.Text.Length));
                            BFS.BRP = Convert.ToUInt16(txb_BRPValue.Text.Substring(0, txb_BRPValue.Text.Length));
                            if(BFS.BRP>=1024)
                            {
                                MessageBox.Show("错误xxx：BRP值超出范围，范围为0-1023，请检查", "提示");
                                return;
                            }
                        }
                        catch
                        {
                            MessageBox.Show("错误xxx：自定义波特率参数有误，请检查","提示");
                            return;
                        }
                    }
                    break;
                case false: // 选择波特率
                    switch(cmb_Baudrate.Text)
                    {
                        case "5k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 399;
                            break;
                        case "10k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 199;
                            break;
                        case "20k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 99;
                            break;
                        case "50k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 39;
                            break;
                        case "100k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 19;
                            break;
                        case "125k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 15;
                            break;
                        case "200k":
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 9;
                            break;
                        case "250k": 
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 7;
                            break;
                        case "400k": 
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 4;
                            break;
                        case "500k": 
                            BFS.tBS1 = 13;
                            BFS.tBS2 = 2;
                            BFS.BRP = 3;
                            break;
                        case "600k": 
                            BFS.tBS1 = 7;
                            BFS.tBS2 = 2;
                            BFS.BRP = 4;
                            break;
                        case "750k":
                            BFS.tBS1 = 7;
                            BFS.tBS2 = 2;
                            BFS.BRP = 3;
                            break;
                        case "800k": 
                            BFS.tBS1 = 3;
                            BFS.tBS2 = 3;
                            BFS.BRP = 4;
                            break;
                        case "1M":
                            BFS.tBS1 = 2;
                            BFS.tBS2 = 1;
                            BFS.BRP = 5;
                            break;
                        default: 
                            break;
                    }
                    break;
                default:
                    break;
            }
            BFS.BRP_H = (byte)(BFS.BRP>>8);
            BFS.BRP_L = (byte)(BFS.BRP);

            BasicFunctionSet_Array[0] = BFS.SendHead0;
            BasicFunctionSet_Array[1] = BFS.SendHead1;
            BasicFunctionSet_Array[2] = BFS.FunctionCode;
            BasicFunctionSet_Array[3] = BFS.RunMode;
            BasicFunctionSet_Array[4] = BFS.tBS1;
            BasicFunctionSet_Array[5] = BFS.tBS2;
            BasicFunctionSet_Array[6] = BFS.BRP_H;
            BasicFunctionSet_Array[7] = BFS.BRP_L;
            BasicFunctionSet_Array[8] = BFS.ForbidAutomaticReSend;
            BasicFunctionSet_Array[28] = GetSumForCommand(BasicFunctionSet_Array);
            BasicFunctionSet_Array[29] = BFS.SendTail;

            switch(serialPort1.IsOpen)
            {
                case true:
                    serialPort1.Write(BasicFunctionSet_Array, 0, 30);
                    break;
                case false:
                    MessageBox.Show("错误xxx：串口没有打开，请检查", "提示");
                    break;
                default: break;
            }

        }

        private void cmb_MainSendDataType0_TextChanged(object sender, EventArgs e)
        {
            ComboBox myComboBox = (ComboBox)sender;
            byte tagIndex = Convert.ToByte(myComboBox.Tag);
            TextBox myTextBox = pl_MainSend.Controls["txb_MainSendData" + tagIndex.ToString()] as TextBox;
            switch(myComboBox.Text)
            {
                case "数据帧":
                    myTextBox.Enabled = true;
                    break;
                case "远程帧":
                    myTextBox.Enabled = false;
                    break;
                default:break;
            }
        }

/******************************* ↓保存为Excel↓ ******************************/
        private Excel.Application G_ea;//定义Word应用程序字段
        private object G_missing = //定义G_missing字段并添加引用
            System.Reflection.Missing.Value;
        private void btn_SaveExcel_Click(object sender, EventArgs e)
        {
            try 
            {
                List<ForSaveExcel_Class> P_CAN = new List<ForSaveExcel_Class>();//创建数据集合
                foreach (DataGridViewRow dgvr in dataGridView1.Rows)
                {
                    P_CAN.Add(new ForSaveExcel_Class()//向数据集合添加数据
                    {
                        序号 = dgvr.Cells[0].Value.ToString(),
                        传输方向 = dgvr.Cells[1].Value.ToString(),
                        时间标识 = dgvr.Cells[2].Value.ToString(),
                        帧类型 = dgvr.Cells[3].Value.ToString(),
                        帧格式 = dgvr.Cells[4].Value.ToString(),
                        帧ID = dgvr.Cells[5].Value.ToString(),
                        数据长度 = dgvr.Cells[6].Value.ToString(),
                        数据 = dgvr.Cells[7].Value.ToString(),
                    });
                }
                SaveFileDialog P_SaveFileDialog =//创建保存文件对话框对象
                    new SaveFileDialog();
                P_SaveFileDialog.Filter = "*.xlsx|*.xlsx";
                P_SaveFileDialog.FileName = "CAN数据-" + DateTime.Now.ToLocalTime().ToString("yyyy年MM月dd日HH点mm分");
                if (DialogResult.OK ==//确认是否保存文件
                    P_SaveFileDialog.ShowDialog())
                {
                    ThreadPool.QueueUserWorkItem(//开始线程池
                    (pp) =>//使用lambda表达式
                    {
                        G_ea = new Microsoft.Office.Interop.Excel.Application();//创建应用程序对象
                        Excel.Workbook P_wk = G_ea.Workbooks.Add(G_missing);//创建Excel文档
                        Excel.Worksheet P_ws = (Excel.Worksheet)P_wk.Worksheets.Add(//创建工作区域
                            G_missing, G_missing, G_missing, G_missing);
                        {
                            P_ws.Cells[1, 1] = "序号";
                            P_ws.Cells[1, 2] = "传输方向";
                            P_ws.Cells[1, 3] = "时间标识";
                            P_ws.Cells[1, 4] = "帧类型";
                            P_ws.Cells[1, 5] = "帧格式";
                            P_ws.Cells[1, 6] = "帧ID";
                            P_ws.Cells[1, 7] = "数据长度";
                            P_ws.Cells[1, 8] = "数据";
                        }
                        for (int i = 1; i < (P_CAN.Count + 1); i++)
                        {
                            P_ws.Cells[i + 1, 1] = P_CAN[i - 1].序号;
                            P_ws.Cells[i + 1, 2] = P_CAN[i - 1].传输方向;
                            P_ws.Cells[i + 1, 3] = P_CAN[i - 1].时间标识;
                            P_ws.Cells[i + 1, 4] = P_CAN[i - 1].帧类型;
                            P_ws.Cells[i + 1, 5] = P_CAN[i - 1].帧格式;
                            P_ws.Cells[i + 1, 6] = P_CAN[i - 1].帧ID;
                            P_ws.Cells[i + 1, 7] = P_CAN[i - 1].数据长度;
                            P_ws.Cells[i + 1, 8] = P_CAN[i - 1].数据;
                        }
                        // P_ws.Columns.ColumnWidth = 100;
                        // P_ws.Cells.ColumnWidth = 100;
                        // P_ws.PageSetup.CenterHorizontally = true;
                        P_ws.Columns.AutoFit();  // 适应自身。
                        P_ws.Columns.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                        P_wk.SaveAs(//保存Word文件
                            P_SaveFileDialog.FileName, G_missing, G_missing, G_missing,
                            G_missing, G_missing, Excel.XlSaveAsAccessMode.xlShared, G_missing,
                            G_missing, G_missing, G_missing, G_missing);
                        ((Excel._Application)G_ea.Application).Quit();//退出应用程序

                        this.Invoke(//调用窗体线程
                            (MethodInvoker)(() =>//使用lambda表达式
                            {
                                MessageBox.Show(//弹出消息对话框
                                    "成功创建Excel文档！", "提示！");
                            }));
                    });
                }
            }
            catch 
            {
                MessageBox.Show("使用Excel表格保存需要安装Office2013及以上版本","警告：");
            }
            
        }
/******************************* ↑保存为Excel↑ ******************************/
        private void btn_SaveTxt_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialogForSPI = new SaveFileDialog();
            //if (dataGridView1.Rows.Count ==0)
            //{
            //    MessageBox.Show("发送框中没有数据", "提示");
            //    return;
            //}
            if(txb_DataShow.TextLength==0)
            {
                MessageBox.Show("发送框中没有数据", "提示");
                return;
            }
            else
            {
                saveFileDialogForSPI.Filter = "文本文件(*.txt)|*.txt";  // 需要增加时间
                saveFileDialogForSPI.FileName = "CAN数据-" + DateTime.Now.ToLocalTime().ToString("yyyy年MM月dd日HH点mm分");
                if (saveFileDialogForSPI.ShowDialog() == DialogResult.OK)
                {
                    StringBuilder str = new StringBuilder();
                    str.Append("序号      传输方向      时间标识          帧类型      帧格式       帧ID    数据长度           数据\r\n");
                    try
                    {
                        //for(int i=0;i<dataGridView1.Rows.Count;i++)
                        //{
                            
                        //    for(int j=0;j<dataGridView1.Columns.Count;j++)
                        //    {
                        //        str.Append(dataGridView1.Rows[i].Cells[j].Value.ToString() + "\t");
                        //    }
                        //    str.Append("\r\n");
                        //}
                        str.Append(txb_DataShow.Text.ToString());

                        StreamWriter sw = new StreamWriter(saveFileDialogForSPI.FileName, true, Encoding.UTF8); // 一定要包含正确的编码方式！！
                        sw.Write(str.ToString());
                        sw.Close();
                        this.Invoke(//调用窗体线程
                        (MethodInvoker)(() =>//使用lambda表达式
                        {
                            MessageBox.Show(//弹出消息对话框
                                "成功创建txt文档！", "提示！");
                        }));
                    }
                    catch
                    {
                        MessageBox.Show("错误：没有保存成功为txt", "提示");
                    }
                }
            }
        }
        
/************************* ↑ 常规功能设置 ↑ **********************************/
        private void chb_All_CheckedChanged(object sender, EventArgs e)
        {
            switch (chb_All.Checked)
            {
                case true:
                    foreach (Control ctl in this.pl_SendBatch.Controls)
                    {
                        if (ctl is CheckBox)
                        {
                            CheckBox cmb = (CheckBox)ctl;
                            cmb.Checked = true;
                        }
                    }
                    break;
                case false:
                    foreach (Control ctl in this.pl_SendBatch.Controls)
                    {
                        if (ctl is CheckBox)
                        {
                            CheckBox cmb = (CheckBox)ctl;
                            cmb.Checked = false;
                        }
                    }
                    break;
                default: break;
            }
        }

        private void pl_SendBatch_MouseClick(object sender, MouseEventArgs e)  // 用于panel控件支持鼠标滚轮，只需要焦点在上面就可以简单实现
        {
            Panel myPanel = (Panel)sender;
            myPanel.Focus();
        }
/************************** ↓窗口关闭事件 -- 主要用于保存配置信息↓ ******************************/
        private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveCFG( );
        }

        public void LoadCFG( )
        {
            {  // tab1 加载
                GetPrivateProfileString("tab1", "tab1_cmb_ModeSel", "正常模式", tab1_cmb_ModeSel, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_cmb_baudrate", "500k", tab1_cmb_baudrate, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_chb_CustomEnable", "false", tab1_chb_CustomEnable, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_chb_autoRetransfer", "false", tab1_chb_autoRetransfer, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_txb_tbs1", "", tab1_txb_tbs1, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_txb_tbs2", "", tab1_txb_tbs2, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_txb_brp", "", tab1_txb_brp, 25, IniFile);
                GetPrivateProfileString("tab1", "tab1_txb_calbaudrate", "", tab1_txb_calbaudrate, 25, IniFile);

                cmb_WorkFunSet.Text = tab1_cmb_ModeSel.ToString();
                cmb_Baudrate.Text = tab1_cmb_baudrate.ToString();
                switch(tab1_chb_CustomEnable.ToString())
                {
                    case "True":
                        chb_CustomEnable.Checked = true;
                        chb_CustomEnable_CheckedChanged(null,null);
                        break;
                    case "False":
                        chb_CustomEnable.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (tab1_chb_autoRetransfer.ToString())
                {
                    case "True":
                        chb_AtuoRetransfer.Checked = true;
                        break;
                    case "False":
                        chb_AtuoRetransfer.Checked = false;
                        break;
                    default: 
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                cmb_tBS1.Text = tab1_txb_tbs1.ToString();
                cmb_tBS2.Text = tab1_txb_tbs2.ToString();
                txb_BRPValue.Text = tab1_txb_brp.ToString();
                txb_CalculateCANBaudrate.Text = tab1_txb_calbaudrate.ToString();
                this.CalculatorBuadrate(null,null);
            }
            { // tab2 加载
                GetPrivateProfileString("tab2", "tab2_txb_ID0", "00000000", tab2_txb_ID0, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID1", "00000000", tab2_txb_ID1, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID2", "00000000", tab2_txb_ID2, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID3", "00000000", tab2_txb_ID3, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID4", "00000000", tab2_txb_ID4, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID5", "00000000", tab2_txb_ID5, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID6", "00000000", tab2_txb_ID6, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID7", "00000000", tab2_txb_ID7, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID8", "00000000", tab2_txb_ID8, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID9", "00000000", tab2_txb_ID9, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID10", "00000000", tab2_txb_ID10, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID11", "00000000", tab2_txb_ID11, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID12", "00000000", tab2_txb_ID12, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_ID13", "00000000", tab2_txb_ID13, 25, IniFile);

                GetPrivateProfileString("tab2", "tab2_txb_MASK0", "00000000", tab2_txb_MASK0, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK1", "FFFFFFFF", tab2_txb_MASK1, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK2", "FFFFFFFF", tab2_txb_MASK2, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK3", "FFFFFFFF", tab2_txb_MASK3, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK4", "FFFFFFFF", tab2_txb_MASK4, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK5", "FFFFFFFF", tab2_txb_MASK5, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK6", "FFFFFFFF", tab2_txb_MASK6, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK7", "FFFFFFFF", tab2_txb_MASK7, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK8", "FFFFFFFF", tab2_txb_MASK8, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK9", "FFFFFFFF", tab2_txb_MASK9, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK10", "FFFFFFFF", tab2_txb_MASK10, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK11", "FFFFFFFF", tab2_txb_MASK11, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK12", "FFFFFFFF", tab2_txb_MASK12, 25, IniFile);
                GetPrivateProfileString("tab2", "tab2_txb_MASK13", "FFFFFFFF", tab2_txb_MASK13, 25, IniFile);

                txb_FilterID0.Text = tab2_txb_ID0.ToString();
                txb_FilterID1.Text = tab2_txb_ID1.ToString();
                txb_FilterID2.Text = tab2_txb_ID2.ToString();
                txb_FilterID3.Text = tab2_txb_ID3.ToString();
                txb_FilterID4.Text = tab2_txb_ID4.ToString();
                txb_FilterID5.Text = tab2_txb_ID5.ToString();
                txb_FilterID6.Text = tab2_txb_ID6.ToString();
                txb_FilterID7.Text = tab2_txb_ID7.ToString();
                txb_FilterID8.Text = tab2_txb_ID8.ToString();
                txb_FilterID9.Text = tab2_txb_ID9.ToString();
                txb_FilterID10.Text = tab2_txb_ID10.ToString();
                txb_FilterID11.Text = tab2_txb_ID11.ToString();
                txb_FilterID12.Text = tab2_txb_ID12.ToString();
                txb_FilterID13.Text = tab2_txb_ID13.ToString();

                txb_FilterMASK0.Text = tab2_txb_MASK0.ToString();
                txb_FilterMASK1.Text = tab2_txb_MASK1.ToString();
                txb_FilterMASK2.Text = tab2_txb_MASK2.ToString();
                txb_FilterMASK3.Text = tab2_txb_MASK3.ToString();
                txb_FilterMASK4.Text = tab2_txb_MASK4.ToString();
                txb_FilterMASK5.Text = tab2_txb_MASK5.ToString();
                txb_FilterMASK6.Text = tab2_txb_MASK6.ToString();
                txb_FilterMASK7.Text = tab2_txb_MASK7.ToString();
                txb_FilterMASK8.Text = tab2_txb_MASK8.ToString();
                txb_FilterMASK9.Text = tab2_txb_MASK9.ToString();
                txb_FilterMASK10.Text = tab2_txb_MASK10.ToString();
                txb_FilterMASK11.Text = tab2_txb_MASK11.ToString();
                txb_FilterMASK12.Text = tab2_txb_MASK12.ToString();
                txb_FilterMASK13.Text = tab2_txb_MASK13.ToString();
            }
            { // tab3加载
                GetPrivateProfileString("tab3", "tab3_chb_IDType0", "标准帧", tab3_chb_IDType0, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_IDType1", "标准帧", tab3_chb_IDType1, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_IDType2", "标准帧", tab3_chb_IDType2, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_IDType3", "标准帧", tab3_chb_IDType3, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_IDType4", "标准帧", tab3_chb_IDType4, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_IDType5", "标准帧", tab3_chb_IDType5, 25, IniFile);
                cmb_MainSendIDType0.Text = tab3_chb_IDType0.ToString();
                cmb_MainSendIDType1.Text = tab3_chb_IDType1.ToString();
                cmb_MainSendIDType2.Text = tab3_chb_IDType2.ToString();
                cmb_MainSendIDType3.Text = tab3_chb_IDType3.ToString();
                cmb_MainSendIDType4.Text = tab3_chb_IDType4.ToString();
                cmb_MainSendIDType5.Text = tab3_chb_IDType5.ToString();

                GetPrivateProfileString("tab3", "tab3_chb_DataType0", "数据帧", tab3_chb_DataType0, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_DataType1", "数据帧", tab3_chb_DataType1, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_DataType2", "数据帧", tab3_chb_DataType2, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_DataType3", "数据帧", tab3_chb_DataType3, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_DataType4", "数据帧", tab3_chb_DataType4, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_chb_DataType5", "数据帧", tab3_chb_DataType5, 25, IniFile);
                cmb_MainSendDataType0.Text = tab3_chb_DataType0.ToString();
                cmb_MainSendDataType1.Text = tab3_chb_DataType1.ToString();
                cmb_MainSendDataType2.Text = tab3_chb_DataType2.ToString();
                cmb_MainSendDataType3.Text = tab3_chb_DataType3.ToString();
                cmb_MainSendDataType4.Text = tab3_chb_DataType4.ToString();
                cmb_MainSendDataType5.Text = tab3_chb_DataType5.ToString();
               //cmb_MainSendDataType0_TextChanged(null, null);   // 不加这个也可，因为加载这个之后，就发生了这个事件，而且这个事件，会引起错误！！

                GetPrivateProfileString("tab3", "tab3_txb_ID0", "00000000", tab3_txb_ID0, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_ID1", "00000001", tab3_txb_ID1, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_ID2", "00000002", tab3_txb_ID2, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_ID3", "00000003", tab3_txb_ID3, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_ID4", "00000004", tab3_txb_ID4, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_ID5", "00000005", tab3_txb_ID5, 25, IniFile);
                txb_MainSendID0.Text = tab3_txb_ID0.ToString();
                txb_MainSendID1.Text = tab3_txb_ID1.ToString();
                txb_MainSendID2.Text = tab3_txb_ID2.ToString();
                txb_MainSendID3.Text = tab3_txb_ID3.ToString();
                txb_MainSendID4.Text = tab3_txb_ID4.ToString();
                txb_MainSendID5.Text = tab3_txb_ID5.ToString();

                GetPrivateProfileString("tab3", "tab3_txb_Data0", "00 11 22 33 44 55 66 77", tab3_txb_Data0, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Data1", "11 22 33 44 55 66 77 88", tab3_txb_Data1, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Data2", "22 33 44 55 66 77 88 99", tab3_txb_Data2, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Data3", "33 44 55 66 77 88 99 AA", tab3_txb_Data3, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Data4", "44 55 66 77 88 99 AA BB", tab3_txb_Data4, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Data5", "55 66 77 88 99 AA BB CC", tab3_txb_Data5, 25, IniFile);
                txb_MainSendData0.Text = tab3_txb_Data0.ToString();
                txb_MainSendData1.Text = tab3_txb_Data1.ToString();
                txb_MainSendData2.Text = tab3_txb_Data2.ToString();
                txb_MainSendData3.Text = tab3_txb_Data3.ToString();
                txb_MainSendData4.Text = tab3_txb_Data4.ToString();
                txb_MainSendData5.Text = tab3_txb_Data5.ToString();

                GetPrivateProfileString("tab3", "tab3_txb_Time0", "100", tab3_txb_Time0, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Time1", "200", tab3_txb_Time1, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Time2", "300", tab3_txb_Time2, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Time3", "400", tab3_txb_Time3, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Time4", "500", tab3_txb_Time4, 25, IniFile);
                GetPrivateProfileString("tab3", "tab3_txb_Time5", "600", tab3_txb_Time5, 25, IniFile);
                txb_MainSendCycleTime0.Text = tab3_txb_Time0.ToString();
                txb_MainSendCycleTime1.Text = tab3_txb_Time1.ToString();
                txb_MainSendCycleTime2.Text = tab3_txb_Time2.ToString();
                txb_MainSendCycleTime3.Text = tab3_txb_Time3.ToString();
                txb_MainSendCycleTime4.Text = tab3_txb_Time4.ToString();
                txb_MainSendCycleTime5.Text = tab3_txb_Time5.ToString();
            }

            { // pl加载
                GetPrivateProfileString("pl", "pl_chb1", "False", pl_chb1, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb2", "False", pl_chb2, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb3", "False", pl_chb3, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb4", "False", pl_chb4, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb5", "False", pl_chb5, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb6", "False", pl_chb6, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb7", "False", pl_chb7, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb8", "False", pl_chb8, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb9", "False", pl_chb9, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb10", "False", pl_chb10, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb11", "False", pl_chb11, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb12", "False", pl_chb12, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb13", "False", pl_chb13, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb14", "False", pl_chb14, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb15", "False", pl_chb15, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb16", "False", pl_chb16, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb17", "False", pl_chb17, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb18", "False", pl_chb18, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb19", "False", pl_chb19, 25, IniFile);
                GetPrivateProfileString("pl", "pl_chb20", "False", pl_chb20, 25, IniFile);

                switch(pl_chb1.ToString())
                {
                    case "True":
                        chb_Send1.Checked = true;
                        break;
                    case "False":
                        chb_Send1.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb2.ToString())
                {
                    case "True":
                        chb_Send2.Checked = true;
                        break;
                    case "False":
                        chb_Send2.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb3.ToString())
                {
                    case "True":
                        chb_Send3.Checked = true;
                        break;
                    case "False":
                        chb_Send3.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb4.ToString())
                {
                    case "True":
                        chb_Send4.Checked = true;
                        break;
                    case "False":
                        chb_Send4.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb5.ToString())
                {
                    case "True":
                        chb_Send5.Checked = true;
                        break;
                    case "False":
                        chb_Send5.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb6.ToString())
                {
                    case "True":
                        chb_Send6.Checked = true;
                        break;
                    case "False":
                        chb_Send6.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb7.ToString())
                {
                    case "True":
                        chb_Send7.Checked = true;
                        break;
                    case "False":
                        chb_Send7.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb8.ToString())
                {
                    case "True":
                        chb_Send8.Checked = true;
                        break;
                    case "False":
                        chb_Send8.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb9.ToString())
                {
                    case "True":
                        chb_Send9.Checked = true;
                        break;
                    case "False":
                        chb_Send9.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb10.ToString())
                {
                    case "True":
                        chb_Send10.Checked = true;
                        break;
                    case "False":
                        chb_Send10.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb11.ToString())
                {
                    case "True":
                        chb_Send11.Checked = true;
                        break;
                    case "False":
                        chb_Send11.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb12.ToString())
                {
                    case "True":
                        chb_Send12.Checked = true;
                        break;
                    case "False":
                        chb_Send12.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb13.ToString())
                {
                    case "True":
                        chb_Send13.Checked = true;
                        break;
                    case "False":
                        chb_Send13.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb14.ToString())
                {
                    case "True":
                        chb_Send14.Checked = true;
                        break;
                    case "False":
                        chb_Send14.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb15.ToString())
                {
                    case "True":
                        chb_Send15.Checked = true;
                        break;
                    case "False":
                        chb_Send15.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb16.ToString())
                {
                    case "True":
                        chb_Send16.Checked = true;
                        break;
                    case "False":
                        chb_Send16.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb17.ToString())
                {
                    case "True":
                        chb_Send17.Checked = true;
                        break;
                    case "False":
                        chb_Send17.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb18.ToString())
                {
                    case "True":
                        chb_Send18.Checked = true;
                        break;
                    case "False":
                        chb_Send18.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb19.ToString())
                {
                    case "True":
                        chb_Send19.Checked = true;
                        break;
                    case "False":
                        chb_Send19.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }
                switch (pl_chb20.ToString())
                {
                    case "True":
                        chb_Send20.Checked = true;
                        break;
                    case "False":
                        chb_Send20.Checked = false;
                        break;
                    default:
                        MessageBox.Show("错误xxx：加载ini时错误，请重启!\n若重启后若仍然提示该信息则删除对应的ini文件！", "提示！");
                        return;
                }


                GetPrivateProfileString("pl", "pl_txbSave1", "", pl_txbSave1, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave2", "", pl_txbSave2, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave3", "", pl_txbSave3, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave4", "", pl_txbSave4, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave5", "", pl_txbSave5, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave6", "", pl_txbSave6, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave7", "", pl_txbSave7, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave8", "", pl_txbSave8, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave9", "", pl_txbSave9, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave10", "", pl_txbSave10, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave11", "", pl_txbSave11, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave12", "", pl_txbSave12, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave13", "", pl_txbSave13, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave14", "", pl_txbSave14, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave15", "", pl_txbSave15, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave16", "", pl_txbSave16, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave17", "", pl_txbSave17, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave18", "", pl_txbSave18, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave19", "", pl_txbSave19, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txbSave20", "", pl_txbSave20, 25, IniFile);

                txb_Specification1.Text = pl_txbSave1.ToString();
                txb_Specification2.Text = pl_txbSave2.ToString();
                txb_Specification3.Text = pl_txbSave3.ToString();
                txb_Specification4.Text = pl_txbSave4.ToString();
                txb_Specification5.Text = pl_txbSave5.ToString();
                txb_Specification6.Text = pl_txbSave6.ToString();
                txb_Specification7.Text = pl_txbSave7.ToString();
                txb_Specification8.Text = pl_txbSave8.ToString();
                txb_Specification9.Text = pl_txbSave9.ToString();
                txb_Specification10.Text = pl_txbSave10.ToString();
                txb_Specification11.Text = pl_txbSave11.ToString();
                txb_Specification12.Text = pl_txbSave12.ToString();
                txb_Specification13.Text = pl_txbSave13.ToString();
                txb_Specification14.Text = pl_txbSave14.ToString();
                txb_Specification15.Text = pl_txbSave15.ToString();
                txb_Specification16.Text = pl_txbSave16.ToString();
                txb_Specification17.Text = pl_txbSave17.ToString();
                txb_Specification18.Text = pl_txbSave18.ToString();
                txb_Specification19.Text = pl_txbSave19.ToString();
                txb_Specification20.Text = pl_txbSave20.ToString();


                GetPrivateProfileString("pl", "pl_cmb_IDType1", "标准帧", pl_cmb_IDType1, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType2", "标准帧", pl_cmb_IDType2, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType3", "标准帧", pl_cmb_IDType3, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType4", "标准帧", pl_cmb_IDType4, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType5", "标准帧", pl_cmb_IDType5, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType6", "标准帧", pl_cmb_IDType6, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType7", "标准帧", pl_cmb_IDType7, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType8", "标准帧", pl_cmb_IDType8, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType9", "标准帧", pl_cmb_IDType9, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType10", "标准帧", pl_cmb_IDType10, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType11", "标准帧", pl_cmb_IDType11, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType12", "标准帧", pl_cmb_IDType12, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType13", "标准帧", pl_cmb_IDType13, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType14", "标准帧", pl_cmb_IDType14, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType15", "标准帧", pl_cmb_IDType15, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType16", "标准帧", pl_cmb_IDType16, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType17", "标准帧", pl_cmb_IDType17, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType18", "标准帧", pl_cmb_IDType18, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType19", "标准帧", pl_cmb_IDType19, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_IDType20", "标准帧", pl_cmb_IDType20, 25, IniFile);
                cmb_SendIDType1.Text = pl_cmb_IDType1.ToString();
                cmb_SendIDType2.Text = pl_cmb_IDType2.ToString();
                cmb_SendIDType3.Text = pl_cmb_IDType3.ToString();
                cmb_SendIDType4.Text = pl_cmb_IDType4.ToString();
                cmb_SendIDType5.Text = pl_cmb_IDType5.ToString();
                cmb_SendIDType6.Text = pl_cmb_IDType6.ToString();
                cmb_SendIDType7.Text = pl_cmb_IDType7.ToString();
                cmb_SendIDType8.Text = pl_cmb_IDType8.ToString();
                cmb_SendIDType9.Text = pl_cmb_IDType9.ToString();
                cmb_SendIDType10.Text = pl_cmb_IDType10.ToString();
                cmb_SendIDType11.Text = pl_cmb_IDType11.ToString();
                cmb_SendIDType12.Text = pl_cmb_IDType12.ToString();
                cmb_SendIDType13.Text = pl_cmb_IDType13.ToString();
                cmb_SendIDType14.Text = pl_cmb_IDType14.ToString();
                cmb_SendIDType15.Text = pl_cmb_IDType15.ToString();
                cmb_SendIDType16.Text = pl_cmb_IDType16.ToString();
                cmb_SendIDType17.Text = pl_cmb_IDType17.ToString();
                cmb_SendIDType18.Text = pl_cmb_IDType18.ToString();
                cmb_SendIDType19.Text = pl_cmb_IDType19.ToString();
                cmb_SendIDType20.Text = pl_cmb_IDType20.ToString();

                GetPrivateProfileString("pl", "pl_cmb_DataType1", "数据帧", pl_cmb_DataType1, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType2", "数据帧", pl_cmb_DataType2, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType3", "数据帧", pl_cmb_DataType3, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType4", "数据帧", pl_cmb_DataType4, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType5", "数据帧", pl_cmb_DataType5, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType6", "数据帧", pl_cmb_DataType6, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType7", "数据帧", pl_cmb_DataType7, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType8", "数据帧", pl_cmb_DataType8, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType9", "数据帧", pl_cmb_DataType9, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType10", "数据帧", pl_cmb_DataType10, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType11", "数据帧", pl_cmb_DataType11, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType12", "数据帧", pl_cmb_DataType12, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType13", "数据帧", pl_cmb_DataType13, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType14", "数据帧", pl_cmb_DataType14, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType15", "数据帧", pl_cmb_DataType15, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType16", "数据帧", pl_cmb_DataType16, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType17", "数据帧", pl_cmb_DataType17, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType18", "数据帧", pl_cmb_DataType18, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType19", "数据帧", pl_cmb_DataType19, 25, IniFile);
                GetPrivateProfileString("pl", "pl_cmb_DataType20", "数据帧", pl_cmb_DataType20, 25, IniFile);
                chb_SendDataType1.Text = pl_cmb_DataType1.ToString();
                chb_SendDataType2.Text = pl_cmb_DataType2.ToString();
                chb_SendDataType3.Text = pl_cmb_DataType3.ToString();
                chb_SendDataType4.Text = pl_cmb_DataType4.ToString();
                chb_SendDataType5.Text = pl_cmb_DataType5.ToString();
                chb_SendDataType6.Text = pl_cmb_DataType6.ToString();
                chb_SendDataType7.Text = pl_cmb_DataType7.ToString();
                chb_SendDataType8.Text = pl_cmb_DataType8.ToString();
                chb_SendDataType9.Text = pl_cmb_DataType9.ToString();
                chb_SendDataType10.Text = pl_cmb_DataType10.ToString();
                chb_SendDataType11.Text = pl_cmb_DataType11.ToString();
                chb_SendDataType12.Text = pl_cmb_DataType12.ToString();
                chb_SendDataType13.Text = pl_cmb_DataType13.ToString();
                chb_SendDataType14.Text = pl_cmb_DataType14.ToString();
                chb_SendDataType15.Text = pl_cmb_DataType15.ToString();
                chb_SendDataType16.Text = pl_cmb_DataType16.ToString();
                chb_SendDataType17.Text = pl_cmb_DataType17.ToString();
                chb_SendDataType18.Text = pl_cmb_DataType18.ToString();
                chb_SendDataType19.Text = pl_cmb_DataType19.ToString();
                chb_SendDataType20.Text = pl_cmb_DataType20.ToString();

                GetPrivateProfileString("pl", "pl_txb_ID1", "00000000", pl_txb_ID1, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID2", "00000001", pl_txb_ID2, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID3", "00000002", pl_txb_ID3, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID4", "00000003", pl_txb_ID4, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID5", "00000004", pl_txb_ID5, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID6", "00000005", pl_txb_ID6, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID7", "00000006", pl_txb_ID7, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID8", "00000007", pl_txb_ID8, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID9", "00000008", pl_txb_ID9, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID10", "00000009", pl_txb_ID10, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID11", "0000000A", pl_txb_ID11, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID12", "0000000B", pl_txb_ID12, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID13", "0000000C", pl_txb_ID13, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID14", "0000000D", pl_txb_ID14, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID15", "0000000E", pl_txb_ID15, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID16", "0000000F", pl_txb_ID16, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID17", "00000010", pl_txb_ID17, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID18", "00000011", pl_txb_ID18, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID19", "00000012", pl_txb_ID19, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_ID20", "00000013", pl_txb_ID20, 25, IniFile);
                txb_SendID1.Text = pl_txb_ID1.ToString();
                txb_SendID2.Text = pl_txb_ID2.ToString();
                txb_SendID3.Text = pl_txb_ID3.ToString();
                txb_SendID4.Text = pl_txb_ID4.ToString();
                txb_SendID5.Text = pl_txb_ID5.ToString();
                txb_SendID6.Text = pl_txb_ID6.ToString();
                txb_SendID7.Text = pl_txb_ID7.ToString();
                txb_SendID8.Text = pl_txb_ID8.ToString();
                txb_SendID9.Text = pl_txb_ID9.ToString();
                txb_SendID10.Text = pl_txb_ID10.ToString();
                txb_SendID11.Text = pl_txb_ID11.ToString();
                txb_SendID12.Text = pl_txb_ID12.ToString();
                txb_SendID13.Text = pl_txb_ID13.ToString();
                txb_SendID14.Text = pl_txb_ID14.ToString();
                txb_SendID15.Text = pl_txb_ID15.ToString();
                txb_SendID16.Text = pl_txb_ID16.ToString();
                txb_SendID17.Text = pl_txb_ID17.ToString();
                txb_SendID18.Text = pl_txb_ID18.ToString();
                txb_SendID19.Text = pl_txb_ID19.ToString();
                txb_SendID20.Text = pl_txb_ID20.ToString();

                GetPrivateProfileString("pl", "pl_txb_Data1", "00 11 22 33 44 55 66 77", pl_txb_Data1, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data2", "11 22 33 44 55 66 77 88", pl_txb_Data2, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data3", "22 33 44 55 66 77 88 99", pl_txb_Data3, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data4", "33 44 55 66 77 88 99 AA", pl_txb_Data4, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data5", "44 55 66 77 88 99 AA BB", pl_txb_Data5, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data6", "55 66 77 88 99 AA BB CC", pl_txb_Data6, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data7", "66 77 88 99 AA BB CC DD", pl_txb_Data7, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data8", "77 88 99 AA BB CC DD EE", pl_txb_Data8, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data9", "88 99 AA BB CC DD EE FF", pl_txb_Data9, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data10", "99 AA BB CC DD EE FF 00", pl_txb_Data10, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data11", "AA BB CC DD EE FF 00 11", pl_txb_Data11, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data12", "BB CC DD EE FF 00 11 22", pl_txb_Data12, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data13", "CC DD EE FF 00 11 22 33", pl_txb_Data13, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data14", "DD EE FF 00 11 22 33 44", pl_txb_Data14, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data15", "EE FF 00 11 22 33 44 55", pl_txb_Data15, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data16", "FF 00 11 22 33 44 55 66", pl_txb_Data16, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data17", "00 11 22 33 44 55 66 77", pl_txb_Data17, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data18", "11 22 33 44 55 66 77 88", pl_txb_Data18, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data19", "22 33 44 55 66 77 88 99", pl_txb_Data19, 25, IniFile);
                GetPrivateProfileString("pl", "pl_txb_Data20", "33 44 55 66 77 88 99 AA", pl_txb_Data20, 25, IniFile);
                txb_SendData1.Text = pl_txb_Data1.ToString();
                txb_SendData2.Text = pl_txb_Data2.ToString();
                txb_SendData3.Text = pl_txb_Data3.ToString();
                txb_SendData4.Text = pl_txb_Data4.ToString();
                txb_SendData5.Text = pl_txb_Data5.ToString();
                txb_SendData6.Text = pl_txb_Data6.ToString();
                txb_SendData7.Text = pl_txb_Data7.ToString();
                txb_SendData8.Text = pl_txb_Data8.ToString();
                txb_SendData9.Text = pl_txb_Data9.ToString();
                txb_SendData10.Text = pl_txb_Data10.ToString();
                txb_SendData11.Text = pl_txb_Data11.ToString();
                txb_SendData12.Text = pl_txb_Data12.ToString();
                txb_SendData13.Text = pl_txb_Data13.ToString();
                txb_SendData14.Text = pl_txb_Data14.ToString();
                txb_SendData15.Text = pl_txb_Data15.ToString();
                txb_SendData16.Text = pl_txb_Data16.ToString();
                txb_SendData17.Text = pl_txb_Data17.ToString();
                txb_SendData18.Text = pl_txb_Data18.ToString();
                txb_SendData19.Text = pl_txb_Data19.ToString();
                txb_SendData20.Text = pl_txb_Data20.ToString();

                GetPrivateProfileString("pl", "pl_txb_Time", "1000", pl_txb_Time, 25, IniFile);
                txb_SendCycleTime.Text = pl_txb_Time.ToString();
            }
        }

        public void SaveCFG( )
        {
            { // 提示信息
                WritePrivateProfileString("警告：不允许更改其中的信息！！否则会出现错误！！", "", "", IniFile);
                WritePrivateProfileString("作者：WeChat：TC4300 QQ:43058655", "", "", IniFile);
                WritePrivateProfileString("软件更新网址：http://user.qzone.qq.com/43058655", "", "", IniFile);
                WritePrivateProfileString("软件版本：V1.0.0", "", "", IniFile);
            }
            { // tab1 保存
                WritePrivateProfileString("tab1", "tab1_cmb_ModeSel", cmb_WorkFunSet.Text, IniFile);
                WritePrivateProfileString("tab1", "tab1_cmb_baudrate", cmb_Baudrate.Text, IniFile);
                WritePrivateProfileString("tab1", "tab1_chb_CustomEnable", chb_CustomEnable.Checked.ToString(), IniFile);
                WritePrivateProfileString("tab1", "tab1_chb_autoRetransfer", chb_AtuoRetransfer.Checked.ToString(), IniFile);
                WritePrivateProfileString("tab1", "tab1_txb_tbs1", cmb_tBS1.Text, IniFile);
                WritePrivateProfileString("tab1", "tab1_txb_tbs2", cmb_tBS2.Text, IniFile);
                WritePrivateProfileString("tab1", "tab1_txb_brp", txb_BRPValue.Text, IniFile);
                WritePrivateProfileString("tab1", "tab1_txb_calbaudrate", txb_CalculateCANBaudrate.Text, IniFile);
            }
            { // tab2 保存
                for (byte temp = 0; temp <= 13;temp++ )
                {
                    TextBox myBox0 = pl_FilterSet.Controls["txb_FilterID"+temp.ToString()] as TextBox;
                    WritePrivateProfileString("tab2", "tab2_txb_ID"+temp.ToString(), myBox0.Text, IniFile);

                    TextBox myBox1 = pl_FilterSet.Controls["txb_FilterMASK" + temp.ToString()] as TextBox;
                    WritePrivateProfileString("tab2", "tab2_txb_MASK" + temp.ToString(), myBox1.Text, IniFile);
                }
            }
            { // tab3 保存
                for (byte temp = 0; temp <= 5;temp++ )
                {
                    ComboBox myCmb0 = pl_MainSend.Controls["cmb_MainSendIDType" + temp.ToString()] as ComboBox;
                    WritePrivateProfileString("tab3", "tab3_chb_IDType" + temp.ToString(), myCmb0.Text, IniFile);

                    ComboBox myCmb1 = pl_MainSend.Controls["cmb_MainSendDataType" + temp.ToString()] as ComboBox;
                    WritePrivateProfileString("tab3", "tab3_chb_DataType" + temp.ToString(), myCmb1.Text, IniFile);

                    TextBox myTxb0 = pl_MainSend.Controls["txb_MainSendID" + temp.ToString()] as TextBox;
                    WritePrivateProfileString("tab3", "tab3_txb_ID" + temp.ToString(), myTxb0.Text, IniFile);

                    TextBox myTxb1 = pl_MainSend.Controls["txb_MainSendData" + temp.ToString()] as TextBox;
                    WritePrivateProfileString("tab3", "tab3_txb_Data" + temp.ToString(), myTxb1.Text, IniFile);

                    TextBox myTxb2 = pl_MainSend.Controls["txb_MainSendCycleTime" + temp.ToString()] as TextBox;
                    WritePrivateProfileString("tab3", "tab3_txb_Time" + temp.ToString(), myTxb2.Text, IniFile);
                }
            }
            { // PANEL保存
                for (byte temp0 = 1; temp0 <= 20; temp0++)
                {
                    CheckBox myBox = pl_SendBatch.Controls["chb_Send" + temp0.ToString()] as CheckBox;
                    WritePrivateProfileString("pl", "pl_chb" + temp0.ToString(), myBox.Checked.ToString(), IniFile);

                    TextBox myTxb = pl_SendBatch.Controls["txb_Specification" + temp0.ToString()] as TextBox;
                    WritePrivateProfileString("pl", "pl_txbSave" + temp0.ToString(), myTxb.Text, IniFile);

                    ComboBox myCmb = pl_SendBatch.Controls["cmb_SendIDType" + temp0.ToString()] as ComboBox;
                    WritePrivateProfileString("pl", "pl_cmb_IDType" + temp0.ToString(), myCmb.Text, IniFile);

                    ComboBox myCmb1 = pl_SendBatch.Controls["chb_SendDataType" + temp0.ToString()] as ComboBox;
                    WritePrivateProfileString("pl", "pl_cmb_DataType" + temp0.ToString(), myCmb1.Text, IniFile);

                    TextBox myTxb0 = pl_SendBatch.Controls["txb_SendID" + temp0.ToString()] as TextBox;
                    WritePrivateProfileString("pl", "pl_txb_ID" + temp0.ToString(), myTxb0.Text, IniFile);

                    TextBox myTxb1 = pl_SendBatch.Controls["txb_SendData" + temp0.ToString()] as TextBox;
                    WritePrivateProfileString("pl", "pl_txb_Data" + temp0.ToString(), myTxb1.Text, IniFile);
                }
                WritePrivateProfileString("pl", "pl_txb_Time", txb_SendCycleTime.Text, IniFile);
            }
            { // 是否删除配置信息!防止配置出错
                if(toDelIniWhenClosing == true)
                {
                    if (File.Exists(@IniFile))//判断文件是不是存在
                    {
                        File.Delete(@IniFile);//如果存在则删除
                        return;
                    }
                    else
                    {
                    }
                }
            }
        }

      

/************************** ↑窗口关闭事件化-- 主要用于保存配置信息↑ ******************************/
        private void tsm_ReserAPP_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("警告:该操作将会在软件关闭时删除配置信息，是否确定继续?", "提示：",  MessageBoxButtons.OKCancel) == DialogResult.Cancel)
            {
                toDelIniWhenClosing = false;
                MessageBox.Show("已经取消当前操作!", "提示!");
                return;
            }
            else { toDelIniWhenClosing = true; }

            if (File.Exists(@IniFile))//判断文件是不是存在
            {
                toDelIniWhenClosing = true;
             //   File.Delete(@IniFile);//如果存在则删除
                MessageBox.Show("操作成功,当软件关闭时会重新加载配置文件!","提示!");
                return;
            }
            else
            {
                MessageBox.Show("当前无配置文件!", "提示!");
                return;
            }
        }

        private void tsm_Help_Click(object sender, EventArgs e)
        {
            Help Frm_Help = new Help();
            // Frm2.Owner = this;
            Frm_Help.Show();
            tsm_Help.Enabled = false;
        }

        private void cmb_DataTypeChange(object sender, EventArgs e)
        {
            ComboBox myComboBox = (ComboBox)sender;
            byte tagIndex = Convert.ToByte(myComboBox.Tag);
            TextBox myTextBox = pl_SendBatch.Controls["txb_SendData" + tagIndex.ToString()] as TextBox;
            switch (myComboBox.Text)
            {
                case "数据帧":
                    myTextBox.Enabled = true;
                    break;
                case "远程帧":
                    myTextBox.Enabled = false;
                    break;
                default: break;
            }
        }
/************************** ↓下面为清空指令↓  ******************************************/
        private void ts_Clear_ButtonClick(object sender, EventArgs e)
        {
            ClearCount_Array[0] = CC.SendHead0;
            ClearCount_Array[1] = CC.SendHead1;
            ClearCount_Array[2] = CC.FunctionCode;
            CC.ClearWay = 0x01; // 全部清除指令
            ClearCount_Array[3] = CC.ClearWay;
            ClearCount_Array[28] = GetSumForCommand(ClearCount_Array);
            ClearCount_Array[29] = CC.SendTail;
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(ClearCount_Array, 0, 30); // 发送30个数据
            }
            else
            {
                MessageBox.Show("错误xxx:请打开对应串口","提示");
            }
        }
        private void ts_ClearTransfer_Click(object sender, EventArgs e)
        {
            ClearCount_Array[0] = CC.SendHead0;
            ClearCount_Array[1] = CC.SendHead1;
            ClearCount_Array[2] = CC.FunctionCode;
            CC.ClearWay = 0x02; // 清除发送
            ClearCount_Array[3] = CC.ClearWay;
            ClearCount_Array[28] = GetSumForCommand(ClearCount_Array);
            ClearCount_Array[29] = CC.SendTail;
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(ClearCount_Array, 0, 30); // 发送30个数据
            }
            else
            {
                MessageBox.Show("错误xxx:请打开对应串口", "提示");
            }
        }

        private void ts_ClearRecv_Click(object sender, EventArgs e)
        {
            ClearCount_Array[0] = CC.SendHead0;
            ClearCount_Array[1] = CC.SendHead1;
            ClearCount_Array[2] = CC.FunctionCode;
            CC.ClearWay = 0x03; // 清除接收！
            ClearCount_Array[3] = CC.ClearWay;
            ClearCount_Array[28] = GetSumForCommand(ClearCount_Array);
            ClearCount_Array[29] = CC.SendTail;
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(ClearCount_Array, 0, 30); // 发送30个数据
            }
            else
            {
                MessageBox.Show("错误xxx:请打开对应串口", "提示");
            }
        }
/************************** ↑下面为清空指令↑  ******************************************/
        private void dataGridView1_Click(object sender, EventArgs e)  // 主要是为了增加进度条！
        {
            if (dataGridView1.ScrollBars == ScrollBars.Vertical)
            {
                return;
            }
            else if (dataGridView1.RowCount >= 2)
            {
                dataGridView1.ScrollBars = ScrollBars.Vertical;
                dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 2;
            }
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if ( dataGridView1.ScrollBars == ScrollBars.Vertical )
            {
                return;
            }
            else if ( dataGridView1.RowCount >= 2 )
            {
                dataGridView1.ScrollBars = ScrollBars.Vertical;
                dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 2;
            }
        }

        /********************************* ↓工具栏点击事件程序↓ ********************************/
        private void MainFromMenuClick(object sender, EventArgs e)
        {
            ToolStripMenuItem ts = sender as ToolStripMenuItem;
            string tsText = ts.Text;
            {
                tsm_Opacity10Percent1.Checked = false;
                tsm_Opacity20Percent1.Checked = false;
                tsm_Opacity30Percent1.Checked = false;
                tsm_Opacity40Percent1.Checked = false;
                tsm_Opacity50Percent1.Checked = false;
                tsm_Opacity60Percent1.Checked = false;
                tsm_Opacity70Percent1.Checked = false;
                tsm_Opacity80Percent1.Checked = false;
                tsm_Opacity90Percent1.Checked = false;
                tsm_Opacity100Percent1.Checked = false;
            }

            switch (tsText)
            {
                case "10%":
                    this.Opacity = 0.1;
                    tsm_Opacity10Percent1.Checked = true;
                    break;
                case "20%":
                    this.Opacity = 0.2;
                    tsm_Opacity20Percent1.Checked = true;
                    break;
                case "30%":
                    this.Opacity = 0.3;
                    tsm_Opacity30Percent1.Checked = true;
                    break;
                case "40%":
                    this.Opacity = 0.4;
                    tsm_Opacity40Percent1.Checked = true;
                    break;
                case "50%":
                    this.Opacity = 0.5;
                    tsm_Opacity50Percent1.Checked = true;
                    break;
                case "60%":
                    this.Opacity = 0.6;
                    tsm_Opacity60Percent1.Checked = true;
                    break;
                case "70%":
                    this.Opacity = 0.7;
                    tsm_Opacity70Percent1.Checked = true;
                    break;
                case "80%":
                    this.Opacity = 0.8;
                    tsm_Opacity80Percent1.Checked = true;
                    break;
                case "90%":
                    this.Opacity = 0.9;
                    tsm_Opacity90Percent1.Checked = true;
                    break;
                case "100%":
                    this.Opacity = 1.0;
                    tsm_Opacity100Percent1.Checked = true;
                    break;
                default: break;
            }
        }

        private void btn_FilterCal_Click(object sender, EventArgs e)
        {
            FilterCal FilterCalFrm = new FilterCal();
            FilterCalFrm.Show();
        }
        /// <summary>
        /// 滤波器解析函数,当控件悬停时发生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FilterAnalysis(object sender, EventArgs e)
        {
            UInt32 FilterID = 0;  // 滤波器ID
            UInt32 FilterMask = 0; // 滤波器MASK

            Button btn_SingleFilterSet = (Button)sender;
            byte tagIndex = Convert.ToByte(btn_SingleFilterSet.Tag);

            TextBox txb_FilterID = pl_FilterSet.Controls["txb_FilterID" + tagIndex.ToString()] as TextBox;
            TextBox txb_FilterMask = pl_FilterSet.Controls["txb_FilterMASK" + tagIndex.ToString()] as TextBox;
            try // 获取滤波器ID
            {
                FilterID = Convert.ToUInt32(txb_FilterID.Text.Substring(0, txb_FilterID.Text.Length), 16);
            }
            catch
            {
                return;
            }
            try // 获取滤波器MASK
            {
                FilterMask = Convert.ToUInt32(txb_FilterMask.Text.Substring(0, txb_FilterMask.Text.Length), 16);
            }
            catch
            {
                return;
            }
            {   // 下面为解析滤波器,主要来自于滤波器计算器
                string FilterStandardIDValue = string.Empty;
                string FilterExtendIDValue = string.Empty;

                string TooltipDisplayS = string.Empty; // 用于在Tooltip显示

                {   // 不管怎样，都检索出标准帧ID和扩展帧ID
                    {
                        UInt32 ID_Temp = (UInt32)(FilterID >> 21);
                        UInt32 Mask_Temp = (UInt32)(FilterMask >> 21);
                        string ID_TempS = Convert.ToString(ID_Temp, 2).PadLeft(11, '0');
                        string Mask_TempS = Convert.ToString(Mask_Temp, 2).PadLeft(11, '0');
                        for (int i = 0; i < ID_TempS.Length; i++)
                        {
                            if (Mask_TempS[i] == '1')
                            {
                                FilterStandardIDValue += ID_TempS[i];
                            }
                            else
                            {
                                FilterStandardIDValue += 'X';
                            }
                            if (i == 2)
                            {
                                FilterStandardIDValue += ' ';
                            }
                        }
                    }
                    {
                        UInt32 ID_Temp = (UInt32)(FilterID >> 3);
                        UInt32 Mask_Temp = (UInt32)(FilterMask >> 3);
                        string ID_TempS = Convert.ToString(ID_Temp, 2).PadLeft(29, '0');
                        string Mask_TempS = Convert.ToString(Mask_Temp, 2).PadLeft(29, '0');
                        for (int i = 0; i < ID_TempS.Length; i++)
                        {
                            if (Mask_TempS[i] == '1')
                            {
                                FilterExtendIDValue += ID_TempS[i];
                            }
                            else
                            {
                                FilterExtendIDValue += 'X';
                            }
                            if ((i == 4) || (i == 12) || (i == 20))
                            {
                                FilterExtendIDValue += ' ';
                            }
                        }
                    }
                }
                {
                    if ((FilterMask & 0x02) == 0x02) // 必须关心,第一位，数据帧和远程帧
                    {
                        if ((FilterID & 0x02) == 0x02) // 为1
                        {
                            TooltipDisplayS = TooltipDisplayS + "远程帧" + " ";
                        }
                        else // 为0
                        {
                            TooltipDisplayS = TooltipDisplayS + "数据帧" + " ";
                        }
                    }
                    else // 不必关心
                    {
                        TooltipDisplayS = TooltipDisplayS + "数据帧和远程帧" + " ";
                    }
                }
                {
                    if ((FilterMask & 0x04) == 0x04) // 必须关心，标准帧和扩展帧
                    {
                        if ((FilterID & 0x04) == 0x04) // 扩展帧
                        {
                            TooltipDisplayS = TooltipDisplayS + "扩展帧" + " ";
                            {
                                TooltipDisplayS = TooltipDisplayS + "扩展帧ID号:" + FilterExtendIDValue + " ";
                            }
                        }
                        else  // 标准帧
                        {
                            TooltipDisplayS = TooltipDisplayS + "标准帧" + " ";
                            {
                                TooltipDisplayS = TooltipDisplayS + "标准帧ID号:" + FilterStandardIDValue + " ";
                            }
                        }
                        
                    }
                    else // 不必关心
                    {
                        TooltipDisplayS = TooltipDisplayS + "标准帧或扩展帧" + " ";
                        TooltipDisplayS = TooltipDisplayS + "标准帧ID号:" + FilterStandardIDValue + " ";
                        TooltipDisplayS = TooltipDisplayS + "扩展帧ID号:" + FilterExtendIDValue + " ";
                    }
                }

                this.toolTip1.SetToolTip(btn_SingleFilterSet, TooltipDisplayS);
            }
        }


        private void tsm_AboutUs_Click(object sender, EventArgs e)
        {
            AboutUs Frm_AboutUs = new AboutUs();
            Frm_AboutUs.Show();
            tsm_AboutUs.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //try
            //{
            //    txb_DataShow.AppendText(sb.ToString());
            //    sb.Clear();
            //}
            //catch
            //{ }
        }

        private void tmr_StrartRefreshCom_Tick(object sender, EventArgs e)
        {
            SerialPortFresh();
            tmr_StrartRefreshCom.Enabled = false;
        }

    }
}
